perm filename PRINT[NEW,LSP] blob sn#418107 filedate 1979-02-09 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00037 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00004 00002	   -*-MIDAS-*-
C00007 00003	IFE QIO,[
C00009 00004		IFE QIO
C00011 00005		IFE QIO
C00013 00006		IFE QIO
C00016 00007	IFN QIO,[
C00020 00008	 CHECK LIST OF FILES IN AR1 FOR VALIDITY.
C00025 00009		IFN QIO
C00028 00010		IFN QIO
C00033 00011	TYOF3:	CAIN TT,33		ALTMODES ARE ALWAYS 1 WIDE
C00036 00012	TYOF4:				.SEE PTYO
C00040 00013	TERPRI AND PTYO FUNCTIONS
C00043 00014	PRINT, PRIN1, PRINC
C00046 00015	MAIN PRINTOUT ROUTINE
C00050 00016	IFN USELESS,[
C00053 00017	PRINT3:	PUSH P,A	MAIN RECURSIVE ENTRY FOR PRINTING
C00058 00018	PRINT A HUNK
C00060 00019	PRINT ATOM DISPATCH, AND PRINT AN ARRAY OR A RANDOM
C00063 00020	IFN QIO,[
C00067 00021	PRINT AN ATOMIC SYMBOL
C00070 00022	PRNN4:	CAIN F,1		A SIGN WITH NO FOLLOWING
C00072 00023	 COROUTINE TO DELIVER UP CHARACTERS OF A PRINT NAME.
C00074 00024	PRINT A FIXNUM
C00077 00025	PRI2B:	MOVM D,TT
C00080 00026	PRINT A FLONUM (SINGLE OR DOUBLE PRECISION)
C00085 00027		IFN DBFLAG
C00087 00028		IFN DBFLAG
C00090 00029	HERE ON FLONUMS < 0.01 (DB%) OR < 0.1 (DB$)
C00095 00030	PRINT A COMPLEX OR A DUPLEX
C00097 00031	IFN BIGNUM,[
C00099 00032	PRBFNA:	HLR A,B
C00101 00033	FLATSIZE, FLATC, EXPLODEC, EXPLODEN, EXPLODE
C00104 00034	EXPLODE: HRRZI R,EXPL1		SUBR 1
C00105 00035	BAKTRACE
C00109 00036	BKTR1A:	CAMGE A,@VBPORG		LETS HOPE THAT BPORG ISN'T SCREWED UP
C00112 00037	BKTR1B:	MOVE D,BKTRP
C00115 ENDMK
C⊗;
;;;   -*-MIDAS-*-
;;;   **************************************************************
;;;   ***** MACLISP ****** PRINT AND FILE-HANDLING FUNCTIONS *******
;;;   **************************************************************
;;;   ** (C) COPYRIGHT 1978 MASSACHUSETTS INSTITUTE OF TECHNOLOGY **
;;;   ****** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) *******
;;;   **************************************************************


SUBTTL	FUNNY PRINTING ROUTINES

PGBOT PRT


IFE D10\QIO,[
RCPSBK:	SETZ
	SIXBIT \RCPOS\
	  1000,,TYIC
	402000,,D
]		;END OF IFE D10\QIO

.NOPOINT:
	PUSHJ P,NOTNOT
	HRRZM A,V.NOPOINT
	POPJ P,


COMMENT |	HERE IS A FINE HACK THAT GOT SUPERSEDED BY CTYP

CTY:	PUSHJ P,TYOI	;THIS IS ALWAYS DONE BY A XCT "Q,CTY - FOR RANDOM Q.
TYOI:	PUSH P,A	; USEFUL MAINLY BECAUSE IT SAVES A. WARNING!!!
	MOVE A,-1(P)	; THIS CODE IS VERY HACKISH, DEPENDENT ON THE OPCODE
	LDB A,[270600,,-1(A)]	; OF XCT (256). THIS ONLY WORKS FOR ASCII
	PUSHJ P,(R)	; CHARS IN THE RANGE 40-57. THUS Q MUST BE AMONG
	JRST POPAJ	;  [ !"#$%&'()*+,-./] (THE BRACKETS ARE META-CHARS!)

|		;END OF COMMENT


;;;	XCT N,CTYP
;;; CAUSES THE N'TH CHARACTER IN TYO1TB TO GET PRINTED VIA
;;; THE ROUTINE IN R.  SYMBOLS ARE DEFINED FOR THESE XCT'S.

CTYP:	PUSHJ P,TYO1C
TYO1C:	PUSH P,A
	HRRZ A,-1(P)
	LDB A,[270400,,-1(A)]
	MOVE A,TYO1TB(A)
	PUSHJ P,(R)
	JRST POPAJ

TYO1TB:
IRP X,,[#,(,),+,-,.,/,|,:,;, ,←,E,D,⊃,.]Z,,[NMBR,LPAR,RPAR,POS
NEG,DOT,SLSH,VBAR,CLN,SEMI,SPC,BAK,E,D,CTLQ,DCML]
%!Z!%=XCT .IRPCNT,CTYP
	"X
TERMIN
IFG .-TYO1TB-20, WARN [TOO MANY TYO1TB CHARACTERS]
IFE QIO,[

SUBTTL	OLD I/O TYO FUNCTION

%TYO:	JSP T,FXNV1
	MOVE A,TT
	ANDI A,177
	PUSH P,CTRUE
TYO:	JUMPL A,TYOLA
	CAIN A,15	;CLOBBERS D - - SAVES ALL OTHERS
	 JRST TYOCR
TYO2:	MOVE D,@VCHRCT
	SOJL D,TYTB1
	CAIN A,11	;TAB
	 JRST TYOTAB
TYO1:	ADDI D,IN0
	MOVEM D,VCHRCT
	CAIN A,"/
	JRST TYO1A
TYO1B:	SETZM LTYOC
TYO3:
IFN USELESS,[
	SKIPGE TYOSW	;TTY-ONLY CHARS DON'T GO TO FILES!
	JRST TYO7
]		;END OF IFN USELESS
IT$	SKIPLE LPTON
IT$	 PUSHJ P,LPTCHAR
	SKIPE TAPWRT
	 PUSHJ P,UTYO
IFN USELESS, TYO7: SKIPG TYOSW	;FILE-ONLY CHARS DON'T GO TO TTY!
	SKIPE TTYOFF
	 POPJ P,
	JRST TTYTYO

TYO1A:	AOS D,LTYOC
	SOJE D,TYO3
	JRST TYO1B

TYOLA:	MOVE D,@VCHRCT	;TYO LOOKAHEAD - RH OF A HAS DESIRED NUMBER OF
	CAIGE D,(A)	; CHARS FOR AN OBJECT ABOUT TO BE PRINTED
	 CAMN D,@VLINEL	;IF ALREADY AT BEGINNING OF LINE, CAN'T WIN ANY BETTER
	  POPJ P,
	PUSHJ P,ICR		;NEED TO OUTPUT A CR SO ATOM WILL FIT
	JFCL
	POPJ P,

STRTYO:	MOVE A,TT
	JRST TYO

;;;	IFE QIO

TYOCR:	MOVE D,@VLINEL		;LINEL HAD DAMNED WELL BETTER BE A FIXNUM,
	CAIGE D,XHINUM		; AND BETWEEN 8 AND HIGHEST NLISP INUM
	 CAIGE D,10
	  JSP D,LINELR
	JRST TYO1

TYOTAB:	SUB D,@VLINEL
	ORCMI D,7
	MOVEI D,11(D)
	SUB D,@VCHRCT
	MOVNS D
	JUMPG D,TYO1
	MOVEM A,LTYOC
	MOVEI D,IN0
	MOVEM D,VCHRCT
TYTB1:	PUSHJ P,ICR
	 JRST TYO1B
	JRST TYO2

;;;	SKIPS IF THE TERPRI IS ACTUALLY DONE.  NO SKIP IF SUPPRESSSED

ICR:	SKIPE V%TERPRI
	 POPJ P,
	MOVE D,@VLINEL		;LINEL HAD DAMNED WELL BETTER BE A FIXNUM,
	CAIGE D,XHINUM		; AND BETWEEN 8 AND HIGHEST NLISP INUM
	 CAIGE D,10
	  JSP D,LINELR
	PUSH FXP,TT
	MOVEI TT,LRCT-1
	MOVE D,VREADTABLE
	HLRZ TT,@TTSAR(D)
	IOR TT,LTYOC
	JUMPN TT,RSTX1
	POP FXP,TT
	AOS (P)
	JRST ITERPRI


;;;	IFE QIO

IFN ITS,[
LPTCHAR:	SKIPN LPTOPD
	PUSHJ P,LPTOPN
	PUSH P,[.IOT LPTC,A]
	JRST CHARCOM
	OPNGEN LPT,1
]		;END OF IFN ITS

UTYO:	PUSH P,[PUSHJ P,UTTYO]	;OUTPUT TO UTAPE [OR OTHER AUXILLARY DEVICE]
CHARCOM:	XCT (P)
	CAIE A,15
	JRST POP1J
	MOVEI A,12
	XCT (P)
	MOVEI A,15
	JRST POP1J

UTOER2:	SETOM UTOBYT
	UNLOCKI
	PUSH P,[UTOER3]
	PUSH P,A
	PUSH P,CPOPAJ
	JRST UTOER1
UTOER3:	SKIPG UTOBYT
	JRST UTOER4
	MOVEI D,TRUTH
	MOVEM D,TAPWRT
UTTYO:	SOSGE UTOBYT
	JRST .+3
	IDPB A,UTOBP
	POPJ P,
	LOCKI
	SKIPL UTOBYT	;INTERVENING INTERRUPT BETWEEN SOSGE AND LOCKI
	.VALUE
	SKIPN UTOOPD
	JRST UTOER2
IT$	MOVE D,[-UTBSIZ,,UTOB]
IT$	.IOT UTOC,D
10$	OUT UTOC,
10$	JRST UTTYO2
10$ D10WF:	LERR [SIXBIT \OUTPUT FAILURE!\]
IT$	PUSHJ P,UTOINT
UTTYO2:	UNLOCKI
	JRST UTTYO

UTOER4:	MOVSI D,(JFCL)	;CONVERT PUSHJ P,UTTYO ON PDL INTO
	MOVEM D,-1(P)	;HARMLESS JFCL, JUST IN CASE THERE IS CR-LF
	POPJ P,

IFN ITS,[
UTOINT:	MOVE D,UTOIBP
	MOVEM D,UTOBP
	MOVEI D,UTBSIZ*BYTSWD
	MOVEM D,UTOBYT
	POPJ P,
UTOIBP:	440700,,UTOB
]		;END OF IFN ITS
;;;	IFE QIO

TTYTYO:
IFN D10,[
SA%	CAIN A,33	;DEC LOSES ALT MODES
SA%	JRST OUT$
	OUTCHR A		;SO OUTPUT CHARACTER
	CAIN A,↑M		;IF IT WAS A CR,
	OUTCHR .+1		; OUTPUT A LF ALSO
	POPJ P,↑J		;MIGHT AS WELL HIDE THE LF IN A POPJ
]		;END OF IFN D10
IFN ITS,[
	CAIN A,↑P		;ITS LOSES ON CTRL/P
	JRST TYOCP
	.IOT TYOC,A
TTYTY1:	SKIPE SPP
	CAIE A,↑M
	POPJ P,
	SKIPN SRNLN1
	POPJ P,
	.CALL RCPSBK	;AFTER TYOING A CR, AND BEING IN DISPLAY PAUSE MODE
	.VALUE		;READ CURSOR POSITION TO SEE IF WE SHOULD PAUSE
	HLRZS D
	CAMGE D,SRNLN1
	POPJ P,
	MOVEI D,[ASCIZ \⊂S--PAUSE-- HIT ↑U TO CONTINUE\]
	SETZM PAUSFL
	PUSHJ P,SRNTYP
	SKIPN PAUSFL
	.HANG
	MOVEI D,PAUSCLR
SRNTYP:	HRLI D,440700	;OUTPUT STRING OF CHARS TO TTY
	PUSH FXP,D	;USES ONLY D, WHICH POINTS TO CHARS
SNTP0:	ILDB D,(FXP)	;MUST SAVE AR2A AND R, EITHER OF
	JUMPE D,PX1J	; WHICH MAY CONTAIN THE CHARS!
	CAIN D,↑P	;MUST BE VERY CIRCUMSPECT ABOUT ↑P
	JRST SNTP1	; - INTERRUPTING BETWEEN ↑P AND NEXT
	.IOT TYOC,D	; CHAR(S) COULD CAUSE AN I/O SCREW
	JRST SNTP0
SNTP1:	HLLOS NOQUIT	;SO TURN ON NOQUIT
	.IOT TYOC,D	;OUTPUT THE ↑P
	ILDB D,(FXP)
	.IOT TYOC,D	;OUTPUT NEXT CHAR
	CAIE D,"H	;IF WAS H OR V, ↑P EXPECTS YET
	CAIN D,"V	; ANOTHER CHAR
	JRST SNTP2
SNTP3:	HLLZS NOQUIT	;SO RELEASE NOQUIT
	SKIPE INTFLG	;MAYBE CHECK FOR INTERRUPTS
	PUSHJ P,CHECKI
	JRST SNTP0

SNTP2:	ILDB D,(FXP)	;HANDLE CASE OF  ↑P H  OR  ↑P V
	.IOT TYOC,D
	JRST SNTP3

TYOCP:	PUSHJ P,ECOCNP
	JRST TTYTY1

PAUSCLR:	ASCIB [⊂R⊂)
]
]		;END OF IFN ITS

]		;END OF IFE QIO
IFN QIO,[

SUBTTL	NEWIO TYO FUNCTION AND RELATED ROUTINES

;;; CALLED BY FUNCTIONS LIKE PRINT WHICH TAKE AN ARG AND
;;; AN OPTIONAL ASCII OUTPUT FILE ARRAY. DOES ARGS CHECKING
;;; AND SETS UP AR1 WITH THE CORRECT OUTPUT FILE(S).
;;; IF ONE ARG IS GIVEN AND THERE ARE NO FILES TO OUTPUT TO
;;; (↑W IS NON-NIL, AND EITHER ↑R OR OUTFILES IS NIL),
;;; THEN A POPJ IS DONE, RETURNING FOR THE CALLING FUNCTION.
;;; LEFT HALF BITS IN AR1:
;;;	400000	RH OF AR1 HAS SINGLE FILE ARRAY (ELSE LIST)
;;;	200000	DO *NOT* OUTPUT TO TTY AS WELL
;;;		IFN SFA, THEN ALSO PRINT/PRINC/PRIN1/TYO BIT
;;;
;;; CALLED BY:
;;;		JSP F,PRNARG
;;;		   XXX,,[QPRINT]	;ATOM FOR WNA ERROR
;;;	-OR-	   XXX,,[<SFA-BIT>,,QPRINT] ;IFN SFA
;;; XXX IS TYPICALLY JFCL.  IF XXX IS NEGATIVE, THE RETURN VALUE
;;; FOR THE FUNCTION IS NIL INSTEAD OF T.

PRNARG:	AOJN T,PRNAR2
	POP P,A
PRNAR$:	SAVE AR1 AR2A CPNAGX
PRNAR0:	SKIPE AR1,TAPWRT	;IF ↑R NOT SET, USE NIL
	 HRRZ AR1,VOUTFILES	;OTHERWISE USE OUTFILES
	JUMPN AR1,PRNAR3
	SKIPE TTYOFF
	 JRST PRNAR8
PRNAR3:
SFA$	HLRZ T,@(F)		;PLACE OPERATIONS FLAG IN AR1
SFA$	TLO AR1,(T)
	TRNN AR1,-1
SFA$	 JRST PRNTTY		;GOING TO THE TTY
SFA%	 JRST 1(F)
	PUSHJ P,MPFLOK
	 JRST 1(F)
PRNAR7:	PUSHJ P,OFCAN
	EXCH A,AR1
	PUSHJ P,[IOL [LOSING OUTPUT FILE SPECS!]]
	EXCH A,AR1
	JUMPE T,PRNAR0
	JRST PRNAR4

IFN SFA,[
PRNTTY:	TLNE AR1,200000		;REALLY GOING TO THE TTY?
	 JRST 1(F)		;NOPE, SO RETURN
	MOVSI T,AS.SFA		;IS C(TYO) AN SFA?
	MOVE R,V%TYO
	TDNN T,ASAR(R)
	 JRST 1(F)		;NOPE, SO ALL IS OK
	HLLZ T,@(F)		;SFA OPERATION MASK
	MOVEI TT,SR.WOM
	TDNN T,@TTSAR(R)	;CAN THE SFA DO THIS OPERATION DIRECTLY?
	 JRST 1(F)		;NOPE, IT WILL HANDLER A LOWER-LEVEL THING
	MOVEI C,(A)		;ARG IS THING TO PRINT/PRINC/PRIN1
	MOVEI AR1,(R)		;THE SFA
	JRST ISTCAL		;DO AN INTERNAL SFA CALL
]		;END IFN SFA

PRNAR2:	CAME T,XC-1
	 JRST PRNAR9
	MOVE A,-1(P)
	MOVEM AR1,-1(P)
	EXCH AR2A,(P)
	PUSH P,CPNAGX
	SKIPN AR1,AR2A
	 AOJA T,PRNAR0
PRNAR4:	JSP T,PRNARK
	 JRST PRNARA		;ERRONEOUS FILE
	 JRST PRNAR6		;LIST OF SOME KIND
SFA$	 SKIPA			;NORMAL RETURN
SFA$	 JRST PRNAR8		;HANDLED THE SFA
PRNAR5:	TLO AR1,600000		;VALID FILE OBJECT
	HLRZ T,@(F)
	TLO AR1,(T)
	JRST 1(F)

PRNAR6:	TLO AR1,200000
	JRST PRNAR3

PRNARA:	TLO AR1,200000		;MAKE ERROR MESSAGE PRINT CORRECTLY
	JRST PRNAR7

PRNAR8:	SKIPGE (F)
	 JRST FALSE
	JRST TRUE

PRNAR9:	HRRZ D,@(F)
	JRST S1WNAL

PNAGX:	RSTR AR2A AR1
CPNAGX:	POPJ P,PNAGX
;;; CHECK LIST OF FILES IN AR1 FOR VALIDITY.
;;; SKIPS ON *FAILURE*.

MPFLOK:	PUSH P,AR1		;MUST PRESERVE LH OF AR1
	MOVEI AR2A,(AR1)
MPFLO1:	JUMPE AR2A,MPFLO2
	HLRZ AR1,(AR2A)
	JSP T,PRNARK
	 JRST MPFLO3		;ERROR
	 JRST MPFLO3		;LIST (NOT ALLOWED WITHIN ANOTHER LIST)
SFA$	 SKIPA			;NORMAL
SFA$	 JFCL			;HANDLED THE SFA
	HRRZ AR2A,(AR2A)
	JRST MPFLO1

MPFLO3:	AOS -1(P)		;ERROR - SKIP
MPFLO2:	POP P,AR1
	POPJ P,

;;; CHECK OUT OBJECT IN AR1.
;;;	SKIP 3 IF AN SFA, AND HANDLED IT
;;;	SKIP 2 IF A VALID, OPEN, NON-BINARY, OUTPUT FILE OBJECT.
;;;	SKIP 1 IF A LIST (ELEMENTS ARE NOT CHECKED).
;;;	SKIP 0 OTHERWISE.

PRNARK:	CAIN AR1,TRUTH		;ARG CHECK FOR PRNARG
	 HRRZ AR1,V%TYO		;FOR T, ASSUME CONTENTS OF TYO
	JSP TT,XFOSP		;MUST BE FILE ARRAY OR SFA
	 JRST PRNRK2
IFN SFA,[
	  JRST PRNRK1
	PUSH P,T		;SAVE T
	MOVEI TT,SR.WOM		;AN SFA
	HLLZ T,@(F)		;THE APPROPRIATE FUNCTION
	TDNN T,@TTSAR(AR1)	;CAN THE SFA DO IT?
	 JRST PRNRK3		;NOPE, RESTORE T AND PROCEED
	PUSHJ FXP,SAV5		;SAVE THE 'WORLD'
	PUSHJ P,SAVX5
	MOVEI C,(A)		;ARGUMENT TO SFA
	PUSHJ P,ISTCAL
	PUSHJ P,RSTX5
	PUSHJ FXP,RST5
	POP P,T
	JRST 3(T)		;TRIPLE-SKIP RETURN
PRNRK3:	POP P,T
	JRST 2(T)		;DOUBLE-SKIP RETURN, LOWER-LEVEL WILL HANDLE IT
PRNRK1:	]	;END IFN SFA
	MOVE TT,TTSAR(AR1)
	TLNE TT,TTS.IO		;MUST BE OUTPUT FILE
	 TLNE TT,TTS<BN+CL>	;MUST NOT BE CLOSED, NOR BINARY
	  JRST (T)		;ERROR
	JRST 2(T)		;SUCCESS - VALID FILE OBJECT

PRNRK2:	MOVEI TT,(AR1)
	LSH TT,-SEGLOG
	SKIPGE ST(TT)
	 JRST 1(T)		;OKAY IF LIST (CALLER USUALLY WILL USE MPFLOK)
	JRST (T)		;ELSE ERROR

IFN SFA,[
;;; FILE-ARRAY OR LIST IN AR1: IF ZERO USE V%TYO
PRTSTO:	PUSH P,PRTSO1		;IN CASE PRTSTR POPJS
	PUSH FXP,F
	PUSH FXP,A
	MOVEI A,(FXP)		;GIVE IT A PDL NUMBER
	JSP F,PRTSTR		;DO SFA CHECKING
	[SO.TYO,,]
	POP FXP,A
	POPI P,1
PRTSO1:	POPJ FXP,.+1		;RETURN TO CALLER
	POPI FXP,2		;HANDLED ALL WE NEEDED TO
	POPJ P,

PRTSTR:	JUMPE AR1,PRTST1	;HANDLE DEFAULT CONDITION SPECIALLY
	JSP T,PRNARK		;CHECK OUT C(AR1)
	 JFCL			;PROBABLY BAD OUTFILES
	 JRST PRTSTL		;A LIST
	 JRST 1(F)		;A FILE ARRAY OR UNHANDLED SFA
	 POPJ P,		;A HANDLED SFA

PRTST1:	HRRZ AR1,V%TYO
	MOVEI TT,SR.WOM		;AN SFA
	HLLZ T,@(F)		;THE APPROPRIATE FUNCTION
	TDNN T,@TTSAR(AR1)	;CAN THE SFA DO IT?
	 JRST PRTST2		;NOPE, RETURN NORMALLY
	PUSHJ FXP,SAV5		;SAVE THE 'WORLD'
	PUSHJ P,SAVX5
	MOVEI C,(A)		;ARGUMENT TO SFA
	PUSHJ P,ISTCAL
	PUSHJ P,RSTX5
	PUSHJ FXP,RST5
	POPJ P,			;RETURN
PRTST2:	SETZ AR1,		;MAKE SURE AR1 IS STILL ZERO
	JRST 1(F)		;THEN RETURN TO CALLER

PRTSTL:	PUSHJ P,MPFLOK		;CHECK THE LIST IN AR1
	 JRST 1(F)		;RETURN IF ALL OK
	PUSHJ P,OFCAN
	EXCH A,AR1
	PUSHJ P,[IOL [LOSING OUTPUT FILE SPECS!]]
	EXCH A,AR1
	JRST PRTSTR
]		;END IFN SFA
;;;	IFN QIO

TYO$:	JSP F,PRNAR$			;USER'S "*TYO" ENTRY
SFA$		[SO.TYO,,QTYO$]
SFA%		[QTYO$]
	JRST %TYO1

%TYO:	JSP F,PRNARG			;USER'S "TYO" ENTRY
SFA%	 JFCL [Q%TYO]
SFA$	 JFCL [SO.TYO,,Q%TYO]
%TYO1:	JSP T,GTRDTB
	PUSHJ P,TYO1
	JRST TRUE

TYO:	SKIPE AR1,TAPWRT		;ENTRY FOR SINGLE-ENTER INTERNALS
	 HRRZ AR1,VOUTFILES		;TEMP ??
SFA$	JSP F,PRTSTO			;DO SFA CHECKING STUFF

$TYO:	PUSH FXP,T			;ENTRY FOR PRIN1, PRINC, GC-PRINTOUT,
	PUSH FXP,TT			;  AND MULTIPLE-ENTER INTERNALS
	PUSH P,[PXTTTJ]	
	JSP T,GTRDTB
TYOPR:	SKIPA TT,A			;MUST SAVE R FOR PRINT
TYO1:	 JSP F,TYOARG
;AT THIS POINT: CHAR IN TT, FILE(S) IN AR1, READTABLE IN AR2A
;MUST SAVE A,B,C,AR1,R
TYO6:	.5LKTOPOPJ
STRTYO:	JUMPGE AR1,TYO5
	TLNN AR1,200000
	 SKIPE TTYOFF
	  JRST TYO6A
	SKIPLE TYOSW
	 JRST TYO6A
	PUSH P,AR1
	HRR AR1,V%TYO
	TLZ AR1,600000	
	PUSHJ P,TYOF
	POP P,AR1
TYO6A:	MOVEI T,(AR1)
	CAIE T,TRUTH
	 JRST TYO6B
	HRR AR1,V%TYO		;T MEANS SAME AS VALUE OF TYO,
	SKIPN TTYOFF		; BUT CAN BE SILENCED BY ↑W
TYO6B:	 SKIPGE TYOSW
	  POPJ P,
	JRST TYOF

TYO5:
REPEAT 2, PUSH P,AR1
	HRRZS -1(P)
	TLNN AR1,200000
	 SKIPE TTYOFF
	  JRST TYO2
	HRR AR1,V%TYO
	SKIPG TYOSW
	 PUSHJ P,TYOF
TYO2:	SKIPL TYOSW
TYO2A:  SKIPN AR1,-1(P)
	  JRST TYO4
	HLRZ AR1,(AR1)
	CAIN AR1,TRUTH
	 JRST TYO2Z
	HLL AR1,(P)
	JRST TYO2B
TYO2Z:	HRRZ AR1,V%TYO
	HLL AR1,(P)
	SKIPN TTYOFF
TYO2B:	 PUSHJ P,TYOF
	HRRZ AR1,@-1(P)
	MOVEM AR1,-1(P)
	JRST TYO2A

TYO4:	POP P,AR1		;PRESERVE AR1
	JRST POP1J

TYOARG:	JSP T,FXNV1
IFN SAIL\ITS, TDNN TT,[777777,,770000]	;UP TO 12. BITS OKAY
IFE SAIL\ITS, TDNN TT,[777777,,777400]	;UP TO 8 BITS OKAY
	 JRST (F)
	JRST TYOAGE
;;;	IFN QIO

;;; TYO ONE CHARACTER TO ONE FILE.  MUST PRESERVE AR1,AR2A
;;;	USER INTERRUPTS LOCKED OUT. (??)
;;;	FILE ARRAY IN AR1.
;;;	READTABLE IN AR2A.
;;;	CHARACTER IN TT (MUST BE PRESERVED).
;;; TYOF HANDLES ALL CHARPOS, LINENUM, AND PAGENUM PROCESSING,
;;; CONTROL CHARACTERS, SAIL MODE OUTPUT, ETC.
;;; ALL CR'S NOT FOLLOWED BY LF'S HAVE LF'S SUPPLIED FOR THEM.
;;; MUST SAVE R FOR PRINT.

TYOFA:	MOVE TT,A
TYOFIL:	.5LKTOPOPJ
TYOF:	TRNN AR1,-1
	 JRST TYOFE
IFN SFA,[
	MOVSI T,AS.SFA		;AN SFA?
	TDNN T,ASAR(AR1)
	 JRST TYOFS0		;NOPE
	PUSHJ FXP,SAV5		;SAVE THE 'WORLD'
	PUSHJ P,SAVX5
	SKIPGE TT		   ;DO A CONVERSION ON FORMAT INFO
	 MOVNI TT,(TT)
	JSP T,FXCONS		;CONS UP A FIXNUM
	HLLZ T,AR1		;HAS THIS SFA BEEN HACKED AT A HIGHER LEVEL?
	TLZ T,600000		;BITS NOT OF INTEREST TO THE SFA
	MOVEI TT,SR.WOM
	TDNE T,@TTSAR(AR1)	;CHECK THE OPERATIONS MASK
	 JRST TYOFS1		;ALRADY DONE IT, SO RETURN
	HRRZS INHIBI		;REALLY DIDN'T WANT THAT .5LKTOPOPJ
	MOVEI C,(A)		;AS THE ARGUMENT TO THE SFA
	MOVEI B,Q%TYO		;A TYO OPERATION
	MOVEI A,(AR1)		;THE SFA ITSELF
	PUSHJ P,ISTCSH		;DO SHORT INTERNAL SFA CALL
TYOFS1:	PUSHJ FXP,RST5
	JRST RSTX5		;RESTORE ACS AND RETURN
TYOFS0:	]	;END IFN SFA
	MOVE T,TTSAR(AR1)
	JUMPL TT,TYOF7		;NEGATIVE => FORMAT INFO
	SKIPGE ATO.LC(T)
	 PUSHJ P,TYOFXL
IT%	CAIN TT,177		;RUBOUT HAS NO PRINT WIDTH
IT%	 JRST TYOF4
	CAIN TT,7		;<BELL> HAS NO PRINT WIDTH
	 JRST TYOF0G
IT$	CAIE TT,177		;ITS RUBOUT PRINTS AS TWO CHARACTERS
	 CAIGE TT,40		;CONTROL CHARACTERS HAVE WIDTH
	  JRST TYOF2		; OF 1 OR 2, OR ELSE ARE FUNNY
TYOF0D:	AOS D,AT.CHS(T)		;INCREMENT CHARPOS
	SKIPE ATO.LC(T)		;SKIP UNLESS LAST CHAR WAS /
	 JRST TYOF0G
	SKIPLE FO.LNL(T)	;ZERO OR NEGATIVE LINEL => INFINITY
	 TLNE T,TTS<IM>		.SEE STERPRI
	  JRST TYOF0E		;FOR IMAGE OUTPUT, NO EXTRA CHARS
	CAMLE D,FO.LNL(T)
	 SKIPE V%TERPRI
	  JRST TYOF0E
	HRLM TT,(P)		;NEW LINE NEEDED BEFORE THIS CHAR
	MOVEI TT,↑M		;BECAUSE OF AUTO-TERPRI
	PUSHJ P,TYOF4
	PUSHJ P,TYOFXL
	MOVEI TT,1
	MOVEM TT,AT.CHS(T)		;SO THIS CHAR WILL BE AT CHARPOS 1
	HLRZ TT,(P)
TYOF0E:	MOVE D,@TTSAR(AR2A)		;GET READTABLE ENTRY FOR THIS
	TLNE D,2000	.SEE SYNTAX	;IF THIS IS A /, SET FLAG
	 HLLOS ATO.LC(T)		; FOR NEXT TIME AROUND
	JRST TYOF4

TYOF0G:	SETZM ATO.LC(T)		;RESET / FLAG
	JRST TYOF4		;OUTPUT CHAR, IGNORING LINEL

TYOF2:	CAIG TT,↑M		;FOUND CONTROL CHAR
	 CAIGE TT,↑H
	  JRST TYOF3		;REGULAR CONTROL CHAR
	JRST @.+1-↑H(TT)	;FORMAT EFFECTOR - PECULIAR
		TYOFBS		;↑H	BACKSPACE
		TYOFTB		;↑I	TAB
		TYOFLF		;↑J	LINE FEED
		TYOF3		;↑K	<NOT REALLY FORMAT CHAR>
		TYOFFF		;↑L	FORM FEED
		TYOFCR		;↑M	CARRIAGE RETURN

TYOFXL:	SETZM ATO.LC(T)		;LINE FEED NEEDED BEFORE THIS CHAR
	CAIE TT,↑J		;FORGET IT IF THIS CHAR IS LF
	 TLNE T,TTS<IM>		;DON'T GENERATE LF FOR IMAGE FILE
	  POPJ P,
	HRLM TT,(P)
	MOVEI TT,↑J
	PUSHJ P,TYOFLF
	HLRZ TT,(P)
	POPJ P,

TYOFE:	EXCH A,AR1
	%WTA [SIXBIT \NOT A FILE - TYO!\]

TYOF3:	CAIN TT,33		;ALTMODES ARE ALWAYS 1 WIDE
	 JRST TYOF0D
	MOVE D,F.MODE(T)	;RANDOM CONTROL CHAR
IFE SAIL,[
IT$	CAIE TT,177		;RUBOUT PRINTS TWO POSITIONS EVEN IN SAIL MODE
	 TLNN D,FBT<SA>		;SKIP IF SAIL MODE FILE
	  AOS AT.CHS(T)		;OTHERWISE CONTROL CHARS ARE 2 WIDE
]	;END OF IFE SAIL
	JRST TYOF0D

TYOFBS:	SKIPLE AT.CHS(T)	;BACKSPACE - UNLESS AGAINST LEFT MARGIN,
	 SOS AT.CHS(T)		; DECREMENT CHARPOS
	SETZM ATO.LC(T)		;CLEAR / FLAG
	JRST TYOF4

TYOFTB:	MOVEI D,7		;TAB FOUND - JUMP TO NEXT
	IORM D,AT.CHS(T)	;MULTIPLE-OF-8 CHARPOS
	JRST TYOF0D

TYOFLF:	AOS D,AT.LNN(T)		;INCREMENT LINENUM
	SKIPLE FO.PGL(T)	;ZERO PAGEL => INFINITY
	 CAMGE D,FO.PGL(T)	;SKIP IF OVER PAGE LENGTH
	  JRST TYOF4
TYOFFF:	SETZM AT.LNN(T)		;ZERO LINE NUMBER
	AOS AT.PGN(T)		;INCREMENT PAGE NUMBER
	TLNN T,TTS.TY		;IF TTY THEN DON'T GIVE END PAGE INT ON ↑L
	 SKIPN FO.EOP(T)	;IF IT HAS AN ENDPAGEFN, THEN
	  JRST TYOF4		; WANT TO GIVE USER INTERRUPT
	PUSHJ P,TYOF4
	MOVEI D,200000+2*FO.EOP+1
	HRLI D,(AR1)
	JRST UINT

TYOF7:	SKIPLE FO.LNL(T)	;INFINITE LINEL
	 TLNE T,TTS<IM>		; OR IMAGE MODE TTY
	  POPJ P,		; => IGNORE FORMAT DATA
	SKIPN V%TERPRI
	SKIPN AT.CHS(T)		;CAN'T DO ANY BETTER THAN TO BE
	 POPJ P,		; AT THE BEGINNING OF A LINE
	MOVEI D,(TT)
	ADD D,AT.CHS(T)
	CAMG D,FO.LNL(T)
	 POPJ P,
	SETZM AT.CHS(T)
	PUSH FXP,TT
	MOVEI TT,↑M		;IF TOO LONG, DO AN AUTO-TERPRI
	PUSHJ P,TYOFCR
	POP FXP,TT
	POPJ P,

TYOFCR:	SETZM AT.CHS(T)		;CR - SET CHARPOS TO ZERO
	PUSHJ P,TYOF4
	SETOM ATO.LC(T)		;SET LF FLAG (MUSTN'T DO UNTIL AFTER IOT
	POPJ P,			; OF CR BECAUSE A **MORE** MIGHT OCCUR)
TYOF4:				.SEE PTYO
IT$	TLNE T,TTS.TY
IT$	 JRST TYOF4C
TYOF6:
TYOF4A:	SKIPL F.MODE(T)		.SEE FBT.CM
	 JRST TYOF5
IFN ITS,[
	MOVE D,F.CHAN(T)	;CHARMODE (UNIT MODE)
	LSH D,27		;TYI USES THIS CODE TOO (SAVES F)
	IOR D,[.IOT TT]
   SPECPRO INTTYX
TYOXCT:	XCT D
   NOPRO
]		;END OF IFN ITS
IFN D10,[
SA$	 OUTCHR TT
IFE SAIL,[
	TLNN T,TTS.TY
	 JRST .+3
	  IONEOU TT
	  JRST .+5
	CAIE TT,33		;NON-SAIL MONITORS LOSE ALTMODES
	 OUTCHR TT
	CAIN TT,33		;FOR THEM, WE OUTPUT ALTMODE AS $
	 OUTCHR C$		; (ON THE TTY ONLY!)
]		;END OF IFE SAIL
]		;END OF IFN D10
IFN D20,[
	PUSHJ FXP,SAV2
	HRRZ 1,F.JFN(T)
	MOVEI 2,(TT)
	BOUT			;OUTPUT THE BYTE
	PUSHJ FXP,RST2
]		;END OF IFN D20
	AOS F.FPOS(T)		;ADJUST FILE POSITION (DOESN'T HURT IF F.FLEN NEG)
C$:	POPJ P,"$

INTTYR:	HRROS INHIBIT		.SEE $IWAIT	;COME HERE AFTER INTERRUPT
	MOVE T,TTSAR(AR1)	;FILE ARRAY MAY HAVE MOVED
	POPJ P,			.SEE TYIXCT TYICAL

TYOF5:				;BLOCK MODE
IFN ITS+D20,[
	IDPB TT,FB.BP(T)	;PUT BYTE IN BUFFER
	SOSLE FB.CNT(T)		;DECREMENT COUNT
]		;END OF IFN ITS+D20
IFN D10,[
	MOVE D,FB.HED(T)	;FOR D10, BYTE POINTER AND COUNT ARE IN BUFFER HEADER
	IDPB TT,1(D)		;PUT BYTE IN BUFFER
	SOSLE 2(D)		;DECREMENT COUNT
]		;END OF IFN D10
	 POPJ P,
	HRLM TT,(P)
	MOVE TT,T
	PUSH FXP,F
	PUSHJ P,IFORCE
	POP FXP,F
	HLRZ TT,(P)
TYOF5Y:	MOVE T,TTSAR(AR1)
	POPJ P,

IFN ITS,[
TYOF4C:	TLNN T,TTS.IM		;DO NOT HACK THIS FOR IMAGE MODE
	 CAIE TT,↑P		;↑P IS THE DISPLAY ESCAPE CODE, AND
	  JRST TYOF4A		; MUST BE TREATED SPECIALLY
	SKIPGE F.MODE(T)	.SEE FBT.CM
	 JRST TYOF4J
	MOVE TT,FB.CNT(T)	;FOR BLOCK MODE, BE CAREFUL
	PUSH FXP,F
	CAIGE T,2		; ABOUT SPLITTING A ↑P-CODE
	 PUSHJ P,IFORCE		; ACROSS A BLOCK BOUNDARY
	POP FXP,F
TYOF4J:	MOVE T,TTSAR(AR1)	;OUTPUT ↑P AS ↑P P
	MOVEI TT,↑P
	PUSHJ P,TYOF4A
	MOVE T,TTSAR(AR1)
	MOVEI TT,"P
	PUSHJ P,TYOF4A
	JRST TYOF5Y
]		;END OF IFN ITS

]		;END OF IFN QIO
SUBTTL	TERPRI AND PTYO FUNCTIONS

IFE QIO,[
%TERPRI:
TERPRI:	MOVEI A,NIL		;SUBR 0
ITERPRI:
	PUSH P,A
	MOVEI A,↑M
	PUSHJ P,TYO
	JRST POPAJ
]		;END OF IFE QIO


IFN QIO,[
%TERPRI:
	JUMPN T,.+3
	PUSH P,R70
	MOVNI T,1
	PUSH P,(P)		;EVEN THOUGH LSUBR (0 . 1)
	SOS T			;PRETEND TO BE (1 . 2) FOR PRNARG'S SAKE
	JSP F,PRNARG		;PRNARG MAY DO A POPJ FOR US - BEWARE!
SFA%	   400000,,[Q%TERPRI]	;BIT 4.9 => RETURN VALUE IS NIL
SFA$	   400000,,[SO.TRP,,Q%TERPRI]	;BIT 4.9 => RETURN VALUE IS NIL
	JRST TERP1

TRP$:	JSP F,PRNAR$
SFA%	   400000,,[QTRP$]
SFA$	   400000,,[SO.TRP,,QTRP$]
	JRST TERP1

TERPRI:	SKIPE AR1,TAPWRT	;1/4-INTERNAL TERPRI
	 HRRZ AR1,VOUTFILES
SFA$	JSP F,PRTSTR		;DO SFA CHECKING STUFF
SFA$	[SO.TRP,,]
TERP1:	JSP T,GTRDTB		;SEMI-INTERNAL TERPRI
	MOVEI A,NIL
ITERPRI:
	PUSH P,A		;INTERNAL TERPRI - SAVES A,B,C
	MOVEI TT,↑M		;MUST HAVE FILE ARRAY IN AR1,
	PUSHJ P,TYO6		; READTABLE IN AR2A
	MOVEI TT,↑J
	PUSHJ P,TYO6
	JRST POPAJ

PTYO:	SKIPE V.RSET		; +TYO: SUBR 2
	 JRST PTYO2
PTYO1:	MOVE TT,(A)		;FIRST ARG IS ASCII VALUE
	CAIN B,TRUTH		;IF T
	 MOVE B,V%TYO
IFN SFA,[
	MOVSI T,AS.SFA		;CHECK IF AN SFA
	TDNE T,ASAR(B)		;SFA BIT SET IN ASAR?
	 JRST PTYO3		;YUP, CALL AS AN SFA
]		;END IFN SFA
	.5LKTOPOPJ
	MOVE T,TTSAR(B)		;SECOND ARG IS FILE
	MOVEI A,TRUTH		;RETURNS T
	JRST TYOF4

IFN SFA,[
PTYO3:	MOVEI C,(A)		;THIRD ARG IS THE FIXNUM
	MOVEI A,(B)		;FIRST ARG IS SFA ITSELF
	MOVEI B,Q%TYO		;TYO OPERATION
	JRST ISTCSH		;DO FAST INTERNAL CALL
]		;END IFN SFA

PTYO2:
IFN SFA,[
	JSP TT,AFOSP		;CHECK FOR AN SFA
	 JFCL
	 SKIPA			;NOPE
	  JRST PTYO3		;YUP, SO CALL IT
]		;END IFN SFA
	JSP T,FXNV1
	MOVEI AR1,(B)
	PUSHJ P,ATOFOK
	UNLOCKI			;MARGINAL DANGER THAT FILE COULD
	JRST PTYO1		; GET SCEWED BY INTERRUPT HERE

]		;END OF IFN QIO
SUBTTL	PRINT, PRIN1, PRINC

IFE QIO,[

%PRINT:
PRINT:	MOVEI R,TYO	;LIKE (PROG2 (TERPRI) (PRIN1 X) (TYO 40))
	PUSHJ P,ITERPRI
CTY1:	PUSHJ P,PRIN1
CTY2:	%SPC%
	POPJ P,


PRIN1B:	MOVE A,B
%PRIN1:
PRIN1:	 SKIPA R,[PR.ATR,,TYO]
%PRINC:
PRINC:	  MOVE R,[PR.PRC,,TYO]
	PUSHJ P,PRINTY
	JRST TRUE
]		;END OF IFE QIO

IFN QIO,[

PRINT:	SKIPE AR1,TAPWRT	;INTERNAL "SUBR" VERSION OF PRINT
	 MOVE AR1,VOUTFILES
SFA$	JSP F,PRTSTR		;DO SFA CHECKING STUFF
SFA$	[SO.PRT,,]
	JRST $PRINT

%PRINT:	 JSP F,PRNARG		;LSUBR (1 . 2)
SFA%	  JFCL [Q%PRINT]
SFA$	  JFCL [SO.PRT,,Q%PRINT]
$PRINT:	JSP T,GTRDTB		;AR1 SHOULD BE SET UP BEFORE COMING HERE
	PUSHJ P,ITERPRI
CTY1:	PUSHJ P,$PRIN1
CTY2:	%SPC%
	POPJ P,

PRIN1B:	MOVE A,B
PRIN1:	SKIPE AR1,TAPWRT	;INTERNAL "SUBR" VERSION OF PRIN1
	 MOVE AR1,VOUTFILES
SFA$	JSP F,PRTSTR
SFA$	[SO.PR1,,]
	JRST $PRIN1
%PRIN1:	
%PR1:	 JSP F,PRNARG		;LSUBR (1 . 2)
SFA%	  JFCL [Q%PR1]
SFA$	  JFCL [SO.PR1,,Q%PR1]
$PRIN1:	MOVE R,[PR.ATR,,$TYO]	;AR1 SHOULD BE SET UP BEFORE COMING HERE
%PR1A:	JSP T,GTRDTB
	PUSHJ P,PRINTY
	JRST TRUE

PRINC:	SKIPE AR1,TAPWRT	;INTERNAL "SUBR" VERSION OF PRINC
	 MOVE AR1,VOUTFILES
SFA$	JSP F,PRTSTR
SFA$	[SO.PRC,,]
	JRST $PRINC
%PRINC:	
%PRC:	JSP F,PRNARG		;LSUBR (1 . 2)
SFA%	  JFCL [Q%PRC]
SFA$	  JFCL [SO.PRC,,Q%PRC]
$PRINC:	MOVE R,[PR.PRC,,$TYO]	;AR1 SHOULD BE SET UP BEFORE COMING HERE
	JRST %PR1A

;;;	SUBR VERSIONS - *PRINT, *PRIN1, *PRINC 
IFE SFA,[
IRPS X,,[PRT$:PR1$:PRC$:]Y,,[$PRINT,$PRIN1,$PRINC]
X:	JSP F,PRNAR$
		[Q!X]

	JRST Y
TERMIN
]		;END IFE SFA

IFN SFA,[
IRPS X,,[PRT$:PR1$:PRC$:]Y,,[$PRINT,$PRIN1,$PRINC]Z,,[SO.PRT,SO.PR1,SO.PRC]
X:	JSP F,PRNAR$
		[Z,,Q!X]
	JRST Y
TERMIN
]		;END IFN SFA
]		;END OF IFN QIO
SUBTTL	MAIN PRINTOUT ROUTINE

;;; ***** OKAY, OUTPUT LOVERS, HERE'S YOUR MAIN PRINT ROUTINE *****

;;; CALLED WITH OBJECT TO PRINT IN A, ADDRESS OF "TYO" ROUTINE IN R.
;;; CLOBBERS A (RETURNS GARBAGE); TO SAVE A OVER PRINTY, USE APRINT.
;;; VARIOUS BITS ARE KEPT IN THE LEFT HALF OF R.
;;; SOME ARE PASSED IN, AND OTHERS ARE INITIALIZED AND USED INTERNALLY.
PR.PRC==400000		;MUST BE SIGN BIT! 0 => PRIN1, 1 => PRINC. (PASSED IN)
PR.ATR==200000		;1 => DO AUTO-TERPRI HACKS
PR.NUM==4000		;SYMBOL LOOKS LIKE A NUMBER SO FAR
PR.NVB==2000		;NOT PROVEN YET THAT VERTICAL BAR NEEDED
PR.EFC==1000		;EMBEDDED FUNNY CHARACTER IN SYMBOL FLAG (1 => NONE SEEN)
PR.NLS==400		;NOT PROVEN YET THAT LEADING SLASH NEEDED
;;; PRINTA EXPECTS B,C,T,TT,R SAFE OVER THE "TYO" ROUTINE.
;;; THE "TYO" ROUTINE GENERALLY EXPECTS AR1 AND AR2A SAFE OVER PRINTA.
;;; USES DIRECTLY OR INDIRECTLY A,B,C,T,TT,D,R,F.
;;; IN THE USELESS VERSION OF LISP, THERE ARE ABBREVIATION HACKS:
;;; PRINTY IS THE ENTRY FOR PRIN1/PRINC; ABBREVIATION IS CONTROLLED
;;; BY BIT 1.1 OF (STATUS ABBREVIATE). TYOSW INDICATES WHETHER
;;; A CHAR IS MEANT FOR TTY, FILES, OR BOTH (IN THIS WAY THE TTY
;;; CAN RECEIVE ABBREVIATIONS WHILE FILES RECEIVE FULL S-EXPRS).
;;; PRINTF IS THE ENTRY FOR FLATSIZE/EXPLODE; ABBREVIATION IS
;;; CONTROLLED BY BIT 1.2 OF (STATUS ABBREVIATE).
;;; PRINTA IS THE ENTRY FOR ALL OTHER PRINT HACKERS; IT
;;; NEVER ABBREVIATES.

IFE USELESS,[
PRINTY:
IFE QIO,[
	SKIPN TAPWRT		;ENTRY FOR PRIN1/PRINC
	 SKIPN TTYOFF		;FAST RETURN IF NO DEVICES ENABLED
	  JRST PRINTA
IT$	SKIPN LPTON
	 POPJ P,
]		;END OF IFE QIO
	SKIPE V%TERPRI		;TERPRI NON-NIL => NEVER AUTO-TERPRI
PRINTF:			;ENTRY FOR FLATSIZE/EXPLODE
PRINTA:  TLZ R,PR.ATR	;OTHER GUYS DON'T WANT AUTO-TERPRI HACKS
PRINT3:	PUSH P,A	;MAIN RECURSIVE ENTRY FOR PRINTING
	ROT A,-SEGLOG	;NOTE THAT A IS SAFE ON PDL
 	SKIPL TT,ST(A)	;MUST DO A ROT, NOT LSH! SEE PRINX
	 JRST PRINX
	%LPAR%		;PRINT A LIST. FIRST TYO A (
PRINT4:	HLRZ A,@(P)
IFN HNKLOG,[
	TLNE TT,HNK
	 JRST PRINH0
PRINH6:
]		;END OF IFN HNKLOG
	PUSHJ P,PRINT3	;NOW PRINT CAR OF THE LIST
	HRRZ A,@(P)
	JUMPE A,PRIN8A	;IF CDR IS NIL, NEED ONLY A )
PRIN7A:	MOVEM A,(P)
	%SPC%		;ELSE SPACE IN BETWEEN
	LSH A,-SEGLOG	;WE KNOW A IS NON-NIL!
 	SKIPGE TT,ST(A)
	 JRST PRINT4	;IF CDR IS NON-ATOMIC, LOOP
	%DOT%		;ELSE DOTTED LIST
	%SPC%
	PUSHJ P,PRIN1A	;SO PRINT THE ATOM AFTER THE LISP DOT
PRIN8A:	%RPAR%		;NOW TYO A )
	JRST POP1J
]		;END OF IFE USELESS

IFN USELESS,[

PRINTY:	MOVEI D,PRINT1		;ENTRY FOR PRIN1/PRINC
	SKIPE V%TERPRI
	 TLZ R,PR.ATR		;TERPRI NON-NIL => NEVER AUTO-TERPRI
	JRST PRINT0

PRINTF:	MOVEI D,PRINT2		;ENTRY FOR FLATSIZE/EXPLODE
	TLZ R,PR.ATR
	JRST PRINT0

APRINT:	PUSH P,A
	PUSH P,CPOPAJ
PRINTA:	MOVEI D,PRIN3A	;ENTRY FOR NO ABBREVIATIONS
	TLZ R,PR.ATR
PRINT0:	PUSH P,A	;CLOBBERS ARG (RETURNS GARBAGE)
	SKIPN V.RSET	;IF IN *RSET MODE, CHECK VALUES OF
	 JRST PRIN0A	; PRINLEVEL AND PRINLENGTH
IRP X,,[%LEVEL,%LENGTH]Y,,[%LV,%LN]
Y!CHK:	SKIPN A,V!X	;NIL IS A VALID VALUE
	 JRST PRT!Y
	SKOTT A,FX
	 JRST Y!ERR
	SKIPGE (A)
	 JRST Y!ERR
PRT!Y:
TERMIN
PRIN0A:	SETOM PRINLV	;PRINLV HAS <ACTUAL PRINT LEVEL>-1
	SETZM ABBRSW	;ASSUME ABBRSW ZERO
	JSP T,RSXST
	MOVEI A,LRCT-2	;GET (STATUS ABBREVIATE)
NW%	HRRZ T,@RSXTB
NW$	LDB T,[001120,,RSXTB]	;PICK UP CHTRAN
	HRRZ A,(P)	;MUST LEAVE ARG IN A FOR PRINT3
	SETZM PRPRCT
	JRST (D)	;DISPATCH TO PRINT1, PRINT2, PRINT3

PRINT1:	SETOM ABBRSW	;PRIN1/PRINC
IT$ Q%	SKIPN LPTON	;IF ANY FILES OPEN, MUST DECIDE WHETHER
	 SKIPE TAPWRT	; OR NOT TO ABBREVIATE THEM
	  JRST PRIN1Q
	SKIPN TTYOFF	;IF NO FILES OPEN, THEN ABBREVIATE FOR TTY
	 JRST PRIN3A
Q%	JRST POPAJ	;IF NO OUTPUT AT ALL, JUST GIVE UP!
PRIN1Q:	TRNN T,1	;ULTIMATE DECISION ON FILE ABBREVIATION
	 HRRZS ABBRSW	; COMES FROM (STATUS ABBREVIATE)
	JRST PRIN3A

PRINT2:	TRNE T,2	;FLATSIZE/EXPLODE - DECIDE WHETHER IT
	 SETOM ABBRSW	; WANTS ABBREVIATION OR NOT
	JRST PRIN3A
PRINT3:	PUSH P,A	;MAIN RECURSIVE ENTRY FOR PRINTING
PRIN3A:	ROT A,-SEGLOG	;NOT LSH! SEE PRINX
	SKIPL TT,ST(A)
	 JRST PRINX	;IF SO, USE AN ATOM PRINTER
	MOVE T,TYOSW	;SAVE OLD VALUE OF TYOSW
	HRLM T,-1(P)	; (I.E. THAT OF PREVIOUS LEVEL)
	JUMPN T,PRINT4	;IF PREVIOUS LEVEL WAS NON-ABBREV,
	SKIPN ABBRSW	; OR IF WE DON'T EVER WANT ABBREV,
	 JRST PRINT4	; THEN NEEDN'T TRY TO ABBREV!
	AOS T,PRINLV	;ELSE INCREMENT LEVEL COUNT
	SKIPE V%LEVEL	;IF PRINLEVEL=NIL, OR IF ACTUAL LEVEL
	 CAMGE T,@V%LEVEL	; IS LESS, THEN DON'T ABBREV
	  JRST PRINT4
	SKIPL ABBRSW
	 SETOM TYOSW
	CAME T,@V%LEVEL	;IF WE'RE EXACTLY EQUAL TO PRINLEVEL,
	 JRST PRIN3F
	MOVEI T,1
	PUSHJ P,PRINLP
	%NMBR%		; SHOOT OUT LEVEL ABBREVIATION
PRIN3F:	SKIPGE ABBRSW	;IF WE ONLY WANT ABBREVIATION,
	 JRST PRINT9	; NEEDN'T GROVEL OVER THE SUBLIST
	HRRZS TYOSW	;ELSE SIGNAL NON-ABBREV ONLY MODE
PRINT4:	PUSH FXP,PRPRCT	;SAVE PARENS COUNTS
	HLLOS PRPRCT	;CLEAR RIGHT PARENS COUNT, AND
	AOS PRPRCT	; INCREMENT LEFT PARENS COUNT
	PUSH FXP,XC-1	;<ACTUAL PRINT LENGTH>-1 FOR THIS LEVEL
	MOVE T,TYOSW	;SAVE CURRENT TYOSW (DETERMINES WHETHER
	HRLM T,(P)	; ABBREV MODE OUTPUT WANTS A ) AT END)
PRINT5:	SKIPN TYOSW	;IF WE ARE IN NON-ABBREV ONLY MODE,
	 SKIPN ABBRSW	; OR IF WE NEVER WANT ABBREV,
	  JRST PRINT7	; THEN DON'T TRY TO ABBREV!
	AOS T,(FXP)	;ELSE INCREMENT PRINT LENGTH
	SKIPE V%LENGTH	;IF PRINLENGTH=NIL, OR IF WE'RE LESS
	 CAMGE T,@V%LENGTH	; THAN IT, THEN DON'T ABBREV
	  JRST PRINT7
	SKIPL ABBRSW
	 SETOM TYOSW
	CAME T,@V%LENGTH
	 JRST PRINT6	;IF WE'RE EXACTLY EQUAL, THEN ABBREV
	MOVEI T,3
	PUSHJ P,PRINLP
REPEAT 3, %DOT%
PRINT6:	SKIPGE ABBRSW	;IF WE DON'T WANT NON-ABBREV ONLY MODE,
	 JRST PRINT8	; THEN CAN IGNORE REST OF LIST
	HRRZS TYOSW	;ELSE SIGNAL NON-ABBREV ONLY MODE
PRINT7:	HRRZ A,(P)
	HRRZ B,(A)
	HLRZ A,(A)
	HRRZ T,-1(FXP)
	ADDI T,1
	SKIPN B
	 HRRM T,PRPRCT
IFN HNKLOG,[
	TLNE TT,HNK
	 JRST PRINH0
PRINH6:
]		;END OF IFN HNKLOG
	PUSHJ P,PRINT3	;SO PRINT THE CAR OF THE LIST
	SETZM PRPRCT
	HRRZ A,(P)
	HRRZ A,(A)
	JUMPE A,PRINT8	;IF CDR IS NIL, NEED ONLY A ) NOW
PRIN7A:	HRRM A,(P)
	%SPC%		;ELSE SPACE BETWEEN
	LSH A,-SEGLOG
	SKIPGE TT,ST(A)
	 JRST PRINT5	;IF CDR NON-ATOMIC, THEN LOOP
	%DOT%		;ELSE WE HAVE A DOTTED LIST
	%SPC%
	HRRZ T,-1(FXP)
	ADDI T,1
	MOVEM T,PRPRCT
	PUSHJ P,PRIN1A	;PRINT THE ATOM AFTER THE LISP DOT
PRINT8:	HLRZ T,(P)	;THIS WILL TELL TYO WHAT TO
	MOVEM T,TYOSW	; DO WITH THE )
PRIN8A:	SUB FXP,R70+1
	POP FXP,PRPRCT
	%RPAR%		;TYO A ) TO END THE LIST
PRINT9:	HLRZ T,-1(P)	;RESTORE TYOSW TO WHAT IT WAS
	MOVEM T,TYOSW	; ON LAST (RECURSIVE!) ENTRY
	JUMPN T,POP1J	;IF AND ONLY IF WE AOS'ED PRINLV,
	SKIPE ABBRSW	; WE MUST NOW SOS IT, AND THEN POP1J
	 SOS PRINLV
	JRST POP1J
]		;END OF IFN USELESS
SUBTTL	PRINT A HUNK

IFN HNKLOG,[

PRINH0:	SKIPN VHUNKP		;IF HUNKP IS NIL, THEN PRINT A HUNK
	 JRST PRINH6		; AS IF IT WERE A LIST CELL
	PUSH FXP,TT
	PUSHJ P,PRINT3		;PRINT A HUNK SEEN FOR A LIST CELL
IFN USELESS,	SETZM PRPRCT
	POP FXP,TT
	MOVSI T,-2
   2DIF [LSH T,(TT)]0,QHUNK1
	HRR T,(P)
	ADD T,R70+1
	PUSH P,T
PRINH1:	MOVEM T,(P)
	HRRZ A,(P)
	HRRZ A,(A)
	CAIN A,-1
	 JRST PRINH3
	%SPC%
	%DOT%
	%SPC%
	PUSHJ P,PRINT3
	HRRZ A,(P)
	HLRZ A,(A)
	CAIN A,-1
	 JRST PRINH3
	%SPC%
	%DOT%
	%SPC%
	PUSHJ P,PRINT3
	MOVE T,(P)
	AOBJN T,PRINH1
PRINH3:	SUB P,R70+1
	HRRZ A,(P)
	HRRZ A,(A)
;	JUMPN A,PRIN7A
	JUMPN A,PRINH4
IFN USELESS,[
	HLRZ T,(P)
	MOVEM T,TYOSW
	MOVEI T,2
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
	%SPC%
	%DOT%
	JRST PRIN8A

PRINH4:	MOVEI TT,(A)		;KLUDGE
	LSH TT,-SEGLOG
	SKIPL ST(TT)
	 JRST PRIN7A
REPEAT 2, %SPC%
	JRST PRIN7A

]		;END OF IFN HNKLOG
SUBTTL	PRINT ATOM DISPATCH, AND PRINT AN ARRAY OR A RANDOM

PRINX:	PUSH P,CPOP1J		;PRINT AN ATOM (ON THE PDL)
PRIN1A:				;TT HAS ST ENTRY
	HRRZ A,-1(P)		;NIL IS SYMBOL, NOT RANDOM!!!
	JUMPE A,PRINIL
   2DIF JRST (TT),.,QLIST	.SEE STDISP	;TT MUST HAVE ST ENTRY
PRIN1Z:	JRST PRINI	;FIXNUM
	JRST PRINO	;FLONUM
DB$	JRST PRINDB	;DOUBLE
CX$	JRST PRINCX	;COMPLEX
DX$	JRST PRINDX	;DUPLEX
BG$	JRST PRINB	;BIGNUM
	JRST PRINN	;SYMBOL
REPEAT HNKLOG, .VALUE	;HUNKS
	JFCL		;RANDOM
IFN .-PRIN1Z-NTYPES+2, WARN [WRONG LENGTH TABLE]
IFN USELESS,[
	MOVEI T,25.
	PUSHJ P,PRINLP
	SETZM PRPRCT
]		;END OF IFN USELESS
	%NMBR%		;ARRAY (AND RANDOM)
	TLNN TT,SA
	 JRST PRINX5
	HRRZ A,-1(P)
	MOVE TT,ASAR(A)
	CAIE TT,ADEAD
	 JRST PRINA2
	SKIPA TT,[440700,,[ASCIZ \DEAD-ARRAY\]]
PRINA1:	 PUSHJ P,(R)
	ILDB A,TT
	JUMPN A,PRINA1
	POPJ P,

PRINA2:
Q$	TLNE TT,AS<FIL>
Q$	 JRST PRNFL
Q$	TLNE TT,AS<JOB>
Q$	 JRST PRNJB
SFA$	TLNE TT,AS.SFA		;SFA?
SFA$	 JRST PRNSR
	JFFO TT,.+1
	HRRZ A,ARYTYP(D)
	TLC TT,AS<SX>		;CROCK FOR NSTORE ARRAYS
	TLNN TT,AS<SX+GCP>
	 SETZ A,
	PUSHJ P,PRINSY
	%NEG%
	HRRZ A,-1(P)
	LDB F,[TTSDIM,,TTSAR(A)]
PRINA3:	HRRZ A,-1(P)
	MOVNI TT,(F)
	MOVE TT,@TTSAR(A)
IFE USELESS,	MOVE C,@VBASE		;BETTER BE A FIXNUM!
IFN USELESS,[
	HRRZ C,VBASE
	CAIE C,QROMAN
	 SKIPA C,(C)
	  PUSHJ P,PROMAN
]		;END OF IFN USELESS
	   PUSHJ P,PRINI9
	SOJE F,PRINA4
	%CLN%
	JRST PRINA3
PRINA4:	%NEG%
PRINX5:	HRRZ TT,-1(P)
PRINL4:	MOVEI C,10	;N BASE 8
	JRST PRINI3
IFN QIO,[

SUBTTL	PRINT A FILE OBJECT, PRINT A JOB OBJECT, PRINT AN SFA

;;; PRINT A JOB OBJECT AS #JOB-|<NAME>|-<ADDRESS>
;;; PRINT A FILE OBJECT AS #FILE-<DIR>-|<NAME>|-<ADDRESS>
;;; PRINT AN SFA AS #SFA-|<SFA-PRINTNAME>|-<ADDRESS>
;;; WHERE <DIR> IS "IN" OR "OUT", <NAME> IS THE TRUENAME,
;;; <SFA-PRINTNAME> IS THE THING GIVEN AS THE THIRD ARG TO CREATE-SFA
;;; AND <ADDRESS> IS THE OCTAL ADDRESS OF THE SAR.

IFN SFA,[
PRNSR:	MOVEI T,[ASCIZ \SFA-\]
	JRST PRNF5
]		;END IFN SFA
PRNJB:	MOVEI T,[ASCIZ \JOB-\]
	JRST PRNF5
PRNFL:	MOVEI T,[ASCIZ \FILE-\]
PRNF5:	PUSHJ P,PRNSTO
	HRRZ A,-1(P)
	MOVE TT,ASAR(A)
SFA$	TLNE TT,AS.SFA		;SFA?
SFA$	 JRST PRNSR1		;YES, PRINT DIFFERENTLY
	PUSH FXP,TT
	TLNE TT,AS.JOB		;DON'T PRINT DIR FOR JOB ARRAY
	 JRST PRNF6
	MOVE TT,TTSAR(A)
;FORMERLY, THIS ROUTINE USED PRINSY TO PRINT IN OR OUT.  BUT, SINCE THIS
;ROUTINE CAN BE CALLED FROM THE GARBAGE COLLECTOR, THE POINTERS COULD BE
;MARKED AND THEREFORE INVALID.  TO AVOID PRINTING LOSSAGE, PRINTING IS DONE
;MANUALLY.
	MOVEI T,[ASCII \IN\]	;ASSUME INPUT FILE
	TLNE TT,TTS<IO>
	 MOVEI T,[ASCII \OUT\]
	PUSHJ P,PRNSTO
	%NEG%
PRNF6:	%VBAR%
	POP FXP,T		    ;SAVED ASAR
	MOVNI TT,LPNBUF
	PUSH FXP,PNBUF+LPNBUF(TT)   ;UNFORTUNATELY, SOMEONE MIGHT BE USING 
	AOJL TT,.-1		    ; PNBUF, SO WE MUST SAVE IT
	HRRZ A,-1(P)
	PUSH FXP,R
20$	MOVE TT,TTSAR(A)	;FOR D20 CLOSED FILE NEEDS SPECIAL HANDLING
20$	TLNN TT,TTS.CL		;CLOSED? (ASAR SAVED IN T)
	TLNE T,AS.JOB		;DON'T GET TRUENAME FOR JOB ARRRAYS
	 JRST PRNJ1
	PUSHJ P,TRU6BT		;GET TRUENAME OF FILE ON FXP
PRNJ2:	PUSH P,[-1]		;MAKE SURE LONG NAMESTRING
	PUSHJ P,6BTNS		;CONVERT THAT TO A NAMESTRING IN PNBUF
	POPI P,1
	POP FXP,R
	MOVEI TT,-LPNBUF+1(FXP)
	MOVSI T,-LPNBUF
PRNF1:	MOVE D,PNBUF(T)		;SWAP PNBUF WITH COPY ON PDL
	EXCH D,(TT)
	MOVEM D,PNBUF(T)
	ADDI TT,1
	AOBJN T,PRNF1
	MOVEI T,-LPNBUF+1(FXP)
	PUSHN FXP,1			;BE SURE STRING ENDS WITH ZEROS
	PUSHJ P,PRNSTO
	POPI FXP,LPNBUF+1		;POP THE CRUD
	%VBAR%
	JRST PRINA4

PRNSTO:	HRLI T,440700
	ILDB A,T
	JUMPE A,CPOPJ
	PUSHJ P,(R)
	JRST .-3

PRNJ1:	HRRZ TT,TTSAR(A)
	HRLI TT,-L.F6BT
20%	PUSH FXP,F.RDEV(TT)
20$	PUSH FXP,F.DEV(TT)
	AOBJN TT,.-1
	JRST PRNJ2
]		;END OF IFN QIO
IFN SFA,[
PRNSR1:	%VBAR%
	MOVEI TT,SR.PNA		;GET THE PNAME
	HRRZ A,-1(P)		;PICK UP ARRAY POINTER
	HRRZ A,@TTSAR(A)
	PUSH FXP,R		;REMEMBER R OVER RECURSIVE CALL TO PRINT
	TLO R,PR.PRC
	PUSHJ P,PRINTA		;PRINT THE NAME
	POP FXP,R
	%VBAR%
	JRST PRINA4
]		;END IFN SFA
SUBTTL	PRINT AN ATOMIC SYMBOL

;PRINIL:
;IFN USELESS, PUSHJ P,PLP1
;	MOVEI A,"(		;PRINT () FOR NIL
;	PUSHJ P,(R)
;	MOVEI A,")
;	JRST (R)

PRINSY:	PUSH P,A
	PUSH P,CPOP1J
	JUMPE A,PRINIL
PRINN:	SKIPA A,-1(P)
PRINIL:	 MOVEI A,[$$$NIL,,]
	JSP C,MAPNAME
	JUMPGE R,PRNN2		.SEE PR.PRC
IFN USELESS,	PUSHJ P,PLP1
PRNN1:	JSP C,(C)		;FOR PRINC, JUST OUTPUT THE CHARS
	 POPJ P,
	MOVEI A,(TT)
	PUSHJ P,(R)
	JRST PRNN1

PRNN2A:
IFN USELESS,[
	HLRZ T,PRPRCT
PRNN2B:	SOJL T,PRNN2C
	%LPAR%
	JRST PRNN2B
PRNN2C:	HRRZS PRPRCT
]	;END OF IFN USELESS
	%VBAR%			;FOR NULL PNAME, PRINT ||
	%VBAR%
	JRST PLP1

PRNN2:	JSP C,(C)		;GET FIRST CHAR
	 JRST PRNN2A		;FOR NULL PNAME, JUST PRINT HANGING LEFT PARENS
	TLO R,PR.NVB+PR.NUM+PR.EFC+PR.NLS
	SETZ F,			;F COUNTS: <# SLASHES,,# CHARS>
	HRRZ A,VREADTABLE
	MOVE D,@TTSAR(A)
	TLNN D,14		;IF NOT A DIGIT OR A SIGN,
	 TLZ R,PR.NUM		; THEN IT ISN'T NUMBER-LIKE
	TLNN D,400		;IF NOT SLASHIFIED AS FIRST CHAR,
	 AOJA F,PRNN3A		; JUST BUMP CHAR COUNTER
	TLZ R,PR.EFC		;ELSE ONE FUNNY CHAR SEEN ALREADY
	TLNE D,171000		;REAL WEIRDIES FORCE VERTICAL BARS
	 TLZ R,PR.NVB
PRNN3:	ADD F,R70+1		;BUMP CHAR COUNT AND SLASH COUNT
PRNN3A:	JSP C,(C)		;GET NEXT CHAR
	 JRST PRNN4
	MOVE D,@TTSAR(A)
	TLNN D,24		;IF IT LOOKS LIKE A NUMBER SO FAR
	 TLZN R,PR.NUM		; BUT THIS NEXT CHAR ISN'T DIGIT OR ARROW,
	  JRST PRNN3B
	TRNE F,777770		; THEN WE NEED A LEADING SLASH IF THERE WERE
	 TLZ R,PR.NLS		; MORE THAN SEVEN LEADING NUMBER-LIKE CHARS
PRNN3B:	TLNN D,100		;IF NOT SLASHIBLE IN FIRST POSITION,
PRNN3C:	 AOJA F,PRNN3A		; JUST BUMP CHAR COUNTER
	TLNN D,2000		;VERTICAL BARS CAN'T HELP A SLASH
	 CAIN TT,"|		; OR VERTICAL BAR, SO COUNT THEM AS
	  AOJA F,PRNN3C		; TWO CHARACTERS AND NO SLASHES
	TLNN D,171000		;REAL WEIRDIES
	 TLZN R,PR.EFC		; OR TWO EMBEDDED FUNNY CHARS
	  TLZ R,PR.NVB		; FORCE VERTICAL BARS
	JRST PRNN3
PRNN4:	CAIN F,1		;A SIGN WITH NO FOLLOWING
	 TLNN D,10		; DIGITS DOESN'T NEED A SLASH
	  CAIA
	   JRST PRNN4A
	TLNE R,PR.NUM		;IF THE WHOLE THING IS NUMBER-LIKE,
	 TLZ R,PR.NLS		; THEN DEFINITELY NEED A LEADING SLASH
PRNN4A:	MOVEI T,2(F)
	TLNN R,PR.NVB
	 JRST PRNN4B
	HLRZ T,F		;WE AREN'T USING VERTICAL BARS
	ADDI T,1(F)		; SO MUST COMPUTE UP ROOM TAKEN BY
	TLNN R,PR.NLS		; CHARS AND SLASHES, PLUS ONE FOR THE SPACE
	 ADDI T,1		; WHICH MAY FOLLOW
PRNN4B:	PUSHJ P,PRINLP
	SKIPN A,-1(P)
	 MOVEI A,[$$$NIL,,]
	JSP C,MAPNAME
	TLNE R,PR.NVB
	 JRST PRNN6
	%VBAR%			;DO THE VERTICAL BAR THING
PRNN5:	JSP C,(C)
	 JRST VBARPOPJ
	CAIE TT,↑M
	 CAIN TT,"|
	  JRST PRNN5A
	MOVE A,VREADTABLE
	MOVE D,@TTSAR(A)
	TLNE D,2000
PRNN5A:	 %SLSH%
	MOVEI A,(TT)
	PUSHJ P,(R)
	JRST PRNN5

VBARPOPJ: %VBAR%
	POPJ P,

PRNN6:	MOVEI F,400
PRNN6A:	JSP C,(C)
	 POPJ P,
20$	PUSH P,B		;B MUST BE PRESERVED
	MOVE A,VREADTABLE
	MOVE D,@TTSAR(A)
	TLOE R,PR.NLS
	 TLNE D,(F)
	  %SLSH%
	MOVEI A,(TT)
	PUSHJ P,(R)
20$	POP P,B
	MOVEI F,100
	JRST PRNN6A
;;; COROUTINE TO DELIVER UP CHARACTERS OF A PRINT NAME.
;;; USES JSP C,(C) TO CALL.  USES B, T; YIELDS CHARS IN TT.
;;; SETUP USES A.  SKIPS UNLESS NO MORE CHARS.

MAPNAME:
	HLRZ B,(A)
	HRRZ B,1(B)
	JSP C,(C)
MAPNM1:	HLRZ T,(B)
	MOVE T,(T)
	TRZ T,1			;FORCE OFF LOW ORDER BIT, IS UNUSED IN ASCII
MAPNM2:	SETZ TT,
	ROTC T,7
	SKIPN T			;ONLY CHECK FOR NULLS IF AT THE END OF THE WORD
	 JUMPE TT,MAPNM3
	JSP C,1(C)
	JRST MAPNM2

MAPNM3:	HRRZ B,(B)
	JUMPN B,MAPNM1
	JRST (C)


;;; ROUTINE TO FEED FORMATTING INFORMATION TO TYO IF DESIRED,
;;; THEN PRINT ANY PENDING LEFT PARENTHESES.
;;; THE LENGTH OF THE ATOM TO BE PRINTED IS IN T.
;;; USES ONLY A AND T.

PRINLP:	TLNN R,PR.ATR
	 JRST PLP1
IFN USELESS,[
	MOVSI T,(T)
	ADD T,PRPRCT
	HLRZ T,T
	ADD T,PRPRCT
]		;END OF IFN USELESS
	TRNE T,777000
	 MOVEI T,777
	HRROI A,1(T)		;ALLOW FOR FOLLOWING SPACE
	 PUSHJ P,(R)
PLP1:				.SEE PRNN1
IFE USELESS,	POPJ P,
IFN USELESS,[
	HLRZ T,PRPRCT
PRINLQ:	SOJL T,CPOPJ
	%LPAR%
	JRST PRINLQ
]		;END OF IFN USELESS
SUBTTL	PRINT A FIXNUM

PRINI:	MOVE A,VBASE
IFN USELESS,	CAIN A,QROMAN
IFN USELESS,	 JRST PRINRM
	SKOTT A,FX
	 JRST BASER
	MOVE C,(A)		;TRUE VALUE OF BASE IN C
	CAIG C,36.
	 CAIGE C,2
	  JRST BASER
PRI2D:	HRRZ A,-1(P)
	JSP T,FXNV1		;THE TYO ROUTINE MUST SAVE TT HERE
IFN USELESS,[
	MOVMS TT		;ESTIMATE LENGTH OF FIXNUM
	JFFO TT,.+2		; ASSUMING OCTAL BASE
	 MOVEI D,43
	MOVNI T,3
	IDIVM D,T		;AVOID CLOBBERING EXTRA ACS
	ADDI T,14
	SKIPGE @-1(P)		;ALLOW FOR MINUS SIGN
	 ADDI T,1
	PUSHJ P,PRINLP
	MOVE TT,@-1(P)
]		;END OF IFN USELESS
	CAIN C,8		;FOR OCTAL NUMBERS, WE MAY WANT
	 JRST PRI2B		; TO USE A FUNNY SHIFTED FORMAT
PRI2C:	JUMPL TT,PRI2Q
	SKIPE V.NOPOINT
	 JRST PRINI2		;HAPPY PRATT?
	CAILE C,10.
	 %POS%
	JRST PRINI2

PRI2Q:	%NEG%
PRI2A:	MOVNS TT
PRINI2:	JSP T,PRI.		;INSERT DECIMAL POINT IF NECESSARY
PRINI9:	MOVEI T,1		;MUST SAVE F - SEE GCPNT1, GCWORRY
	TLZN TT,400000		;IF NUMBER COULD BE MOBY, THEN MOVE HIGH ORDER BIT
PRINI3:	 SETZ T,		.SEE FP4B1	;MUSTN'T DISTURB B
	JSP D,PRINI5
	SKIPE TT,T
	 PUSHJ P,PRINI3
FP7A1:	HLRZ A,(P)
FP7B:	MOVEI A,"0(A)
	CAIE A,".
	 JRST (R)
	%DCML%
	POPJ P,

PRINI5:	DIVI TT-1,(C)
	CAILE TT,9
	 ADDI TT,"A-"9-1	;KLUDGY DIGITS GREATER THAN 9 ARE "A, B, C, ..., Y, Z"
PRINI7:	HRLM TT,(P)
	JRST (D)

PRI.:	CAIN C,10.		;IF THE RADIX IS 10.
	 SKIPE V.NOPOINT	; AND *NOPOINT IS NOT SET,
	  JRST (T)		; THEN KLUDGILY ARRANGE
	HRLI T,".-"0		; TO PRINT A "." AFTER THE
	HLLM T,(P)		; DIGITS ARE PRINTED
	PUSH P,[FP7A1]
	JRST (T)
PRI2B:	MOVM D,TT
	TRNN D,777
	 TLNN D,-1
	  JRST PRI2C
	MOVEI T,(C)
	MOVE C,VREADTABLE
	MOVE D,TT
	MOVEI TT,LRCT-1		;RH OF LAST RCT ENTRY IS (STATUS ←)
	HRRZ C,@TTSAR(C)
	EXCH T,C
	MOVE TT,D
	JUMPE T,PRI2C
	MOVNI D,11		;PRINT OUT AS ONE OF:
	TRNE TT,777000		;	NNNNNNNNN←11
	 JRST PRI2B3		;	NNNNNN←22
	MOVNI D,22		;	NNN←33
	TLNN TT,777		;	N←41
	 MOVNI D,33		; IN ORDER THAT LOSERS NEED NOT
	TLNN TT,77777		; COUNT ALL THE ZEROS OF AN
	 MOVNI D,41		; OCTAL NUMBER.
PRI2B3:	ASH TT,(D)
	PUSH FXP,D
	PUSHJ P,PRI2C
	%BAK%
	POP FXP,TT
	JRST PRI2A

IFN USELESS,[
PROMAN:	AOS (P)
	JRST PRINR0

PRINRM:	HRRZ A,-1(P)
	JSP T,FXNV1
PRINR0:	MOVEI C,10.
	JUMPLE TT,PRI2D
	CAIL TT,4000.
	JRST PRI2D
	MOVEI T,15.
	PUSHJ P,PRINLP
	SETZ T,
PRINR1:	IDIVI TT,10.
	HRLM D,(P)
	ADDI T,1
	JUMPE TT,PRINR2
	PUSHJ P,PRINR1
PRINR2:	HLRZ TT,(P)
	SUBI T,1
	JUMPE TT,CPOPJ
	CAIE TT,9
	JRST PRINR3
	HLRZ A,PRINR9(T)
	PUSHJ P,(R)
	HLRZ A,PRINR9+1(T)
	JRST (R)

PRINR3:	CAIE TT,4
	JRST PRINR4
	HLRZ A,PRINR9(T)
	PUSHJ P,(R)
	HRRZ A,PRINR9(T)
	JRST (R)

PRINR4:	CAIGE TT,5
	JRST PRINR6
	SUBI TT,5
	HRRZ A,PRINR9(T)
PRINR5:	PUSHJ P,(R)
PRINR6:	SOJL TT,CPOPJ
	HLRZ A,PRINR9(T)
	JRST PRINR5

PRINR9:	"I,,"V
	"X,,"L
	"C,,"D
	"M,,
]		;END OF IFN USELESS
SUBTTL	PRINT A FLONUM (SINGLE OR DOUBLE PRECISION)

IFN DBFLAG,[
PRINDB:	
IFN USELESS,[
	MOVEI T,30.		;GROSS ESTIMATE OF LENGTH OF DOUBLE
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
KA	HRRZ A,-1(P)
KA	MOVE T,(A)
KA	MOVE TT,1(A)
KIKL	DMOVE T,@-1(P)
DFP0:
KA	MOVEI B,66		;PRECISION OF "SOFTWARE FORMAT" DOUBLE
KIKL	MOVEI B,76		;PRECISION OF "HARDWARE FORMAT" DOUBLE
	JRST FP0A
]		;END OF IFN DBFLAG

PRINO:
IFN USELESS,[
	MOVEI T,17.		;GROSS ESTIMATE OF LENGTH OF FLONUM
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
	MOVE T,@-1(P)
;A FLONUM TO PRINT IS IN T
FP0:
DB$	MOVEI B,33		;PRECISION OF A FLONUM IN BITS
DB$	SETZ TT,
FP0A:	JUMPGE T,FP0B
	%NEG%
DB%	MOVNS T
DB$ KA	DFN T,TT
DB$ KIKL  DMOVN T,T
FP0B:
;A POSITIVE FLONUM TO PRINT IS IN T (DB$: AND TT); IF DB$, PRECISION IN BITS IS IN B
FP1:
IFN DBFLAG,[
	MOVE F,T		;MAKE A COPY OF NUMBER WITH JUST THE
	AND F,[777400,,]	; MOST SIGNIFICANT BIT SET (ASSUME ARG NORMALIZED)
	PUSH FXP,F		;THIS WILL BE USED FOR A MASK AFTER SCALING
	PUSH FXP,R70		; DOWN BY THE CONTENTS OF B (PRECISION)
	SETZ F,			;F WILL BE THE EXPONENT TO PRINT FOR E/D NOTATION
	CAMGE T,[0.1]
]		;END OF IFN DBFLAG
DB%	SETZB TT,F		;TT IS SECOND WORD FOR T; F WILL BE EXPONENT
DB%	CAMGE T,[0.01]
	 JRST FP4		;0.01 (OR 0.1) AND 1.0↑8 ARE CHOSEN SO THAT THE
	CAML T,[1.0↑8]		; FRACTIONAL PART WILL HAVE AT LEAST ONE
	 JRST FP4E0		; BIT, BUT NOT LOSE ANY OFF THE RIGHT END
DB$	CAILE B,33		;FOR DOUBLE PRECISION, MUST ARRANGE TO PRINT "D0"
DB$	 JRST FP4B1		; AT THE END OF THE NUMBER
IFE DBFLAG,[
;A POSITIVE FLONUM BETWEEN .01 AND 1.0↑8 IS IN T
FP3:	SETZB TT,D
	ASHC T,-33		;SPLIT EXPONENT PART OFF - MANTISSA IN TT
	ASHC TT,-243(T)		;SPLIT NUMBER INTO INTEGRAL AND FRACTIONAL PART
	MOVSI F,200000		;COMPUTE POSITION OF LAST SIGNIFICANT BITS
	ASH F,-243+<43-33>(T)	;F GETS A VALUE EQUAL TO 1/2 LSB
	PUSH FXP,F
	PUSH FXP,D		;SAVE FRACTION
	MOVEI C,10.		;PRINT INTEGER PART AS A DECIMAL FIXNUM
	PUSHJ P,PRINI3
	%DCML%			;PRINT DECIMAL POINT
	POP FXP,TT
;NOW TT HAS FRACTION INFO BITS, AND (FXP) HAS SLIDING MASK BIT (TOLERANCE)
FP3A:	MOVE T,TT		;REMAINING INFO BITS IN TT
	MULI T,10.		;T GETS NEXT DIGIT TO PRINT, MORE OR LESS
	POP FXP,F
	JFCL 8,.+1		;CLEAR OVERFLOW
	IMULI F,10.		;OVERFLOW ON (FSC 231400000001 0) AND (FSC 175631463150 0)
	JFCL 8,FP3A1		;CUT OFF WHEN MASK BIT OVERFLOWS
	CAMGE TT,F
	 JRST FP3A1		; OR WHEN REMAINING INFO BITS ARE BELOW MASK
	MOVN D,F
	TLZ D,400000
	CAMLE TT,D
	 AOJA T,FPX0		;LAST SIG DIGIT, BUT ROUND UPWARDS
	PUSH FXP,F
	PUSHJ P,FPX0		;OUTPUT A DIGIT, AND GO AROUND FOR ANOTHER
	JRST FP3A

FP3A1:	TLNE TT,200000		;SIZE OF REMAINDER DETERMINES ROUNDING
	 ADDI T,1
FPX0:	MOVEI A,"0(T)		;COME HERE TO OUTPUT A DIGIT IN T
	JRST (R)
]		;END OF IFE DBFLAG
IFN DBFLAG,[

;FALLS THROUGH
;;;	IFN DBFLAG

;FALLS IN

;A POSITIVE FLONUM BETWEEN 0.1 AND 10.0↑8 IS IN T AND TT; PRECISION IN BITS IS IN B
; ON FXP, A TWO-WORD MASK VALUE, AS YET UNSCALED BY THE CONTENTS OF B
FP3:
KA	ASH TT,10		;PUT NUMBER IN HARDWARE FORMAT
	LDB F,[331000,,T]	;GET EXPONENT (CANNOT BE LARGER THAN 200+33)
	TLZ T,377000		;CLEAR EXPONENT FROM FRACTION
	PUSH FXP,TT
	SETZ D,
	ASHC TT,-233(F)		;CALCULATE LOW ALIGNED FRACTION WORD
	PUSH FXP,D
	MOVE TT,-1(FXP)
	ASHC T,-233(F)		;CALCULATE HIGH ALIGNED FRACTION WORD
	MOVEM TT,-1(FXP)	;INTEGER PART IS IN T
KA	MOVE TT,-3(FXP)		;GET MASK INTO TT AND D
KA	MOVE D,-2(FXP)
KA	ASH D,10		;CONVERT TO HARDWARE FORMAT
KIKL	DMOVE TT,-3(FXP)
	LDB F,[331000,,TT]	;GET EXPONENT
	TLZ TT,377000		;CLEAR EXPONENT, LEAVING FRACTION
	SUBI F,(B)
	ASHC TT,-200+4(F)	;CALCULATE MASK FRACTION VALUE, BINARY POINT BELOW BIT 4.5
KA	MOVEM TT,-3(FXP)	;SAVE IT BACK ON FXP
KA	MOVEM D,-2(FXP)
KIKL	DMOVEM TT,-3(FXP)
	MOVE TT,T		;PUT INTEGER PART IN TT
	MOVEI C,10.		;PRINT INTEGER PART IN RADIX 10.
	PUSHJ P,PRINI3		;PRESERVES B
	%DCML%
	POP FXP,TT
	POP FXP,T
	ASHC T,-4		;ALIGN FRACTION SO BINARY POINT IS BELOW BIT 4.5

;FALLS THROUGH
;;;	IFN DBFLAG

;FALLS IN

;FRACTION IN T,TT WITH BINARY POINT BELOW BIT 4.5; MASK IN -1(FXP),(FXP)
DFP3A:
	IMULI T,10.		;MULTIPLY FRACTION BY 10.
	MULI TT,10.
	ADD T,TT
	MOVE TT,D
	LDB A,[370400,,T]	;GET NEXT DIGIT (BITS 4.8-4.5) IN A
	MOVEI A,"0(A)		;MAKE IT ASCII
	TLZ T,360000		;FORM REMAINDER IN TT,D
	EXCH T,-1(FXP)		;EXCHANGE FRACTION WITH MASK
	EXCH TT,(FXP)
	IMULI T,10.		;MULTIPLY MASK BY 10.
	MULI TT,10.
	ADD T,TT
	MOVE TT,D
	CAMGE T,-1(FXP)
	 JRST DFP3A1
	CAMG T,-1(FXP)
	 CAMLE TT,(FXP)
	  JRST DFP3A8		;LAST DIGIT IF MASK > FRACTION
DFP3A1:
KA	SETCM D,T		;NEGATE MASK
KA	MOVN F,TT
KA	TLZ F,400000
KA	SKIPN F
KA	 ADDI D,1
KIKL	MOVE D,T
KIKL	MOVE F,TT
KIKL	DMOVN T,T
KA	TLZ D,760000		;FORM 1-MASK
KIKL	TLZ T,760000
KA	CAMLE D,-1(FXP)
KIKL	CAMLE T,-1(FXP)
	 JRST DFP3A2
KA	CAML D,-1(FXP)
KIKL	CAML T,-1(FXP)
KA	 CAMGE F,(FXP)
KIKL	 CAMGE TT,(FXP)
	  AOJA A,DFP3A9		;LAST DIGIT, ROUNDED UP, IF FRACTION > 1-MASK
DFP3A2:
KA	EXCH T,-1(FXP)		;EXCHANGE BACK MASK FOR FRACTION
KA	EXCH TT,(FXP)
KIKL	DMOVE T,-1(FXP)
KIKL	MOVEM D,-1(FXP)
KIKL	MOVEM F,(FXP)
	PUSHJ P,(R)		;OTHERWISE OUTPUT DIGIT AND
	JRST DFP3A		; GO AROUND AGAIN

DFP3A8:	MOVE TT,-1(FXP)		;ROUND LAST DIGIT UP IF FRACTION >= 1/2
	TLNE TT,10000
	 ADDI A,1
DFP3A9:	SUB FXP,R70+2
	JRST (R)

KIKL	D10.0:	10.0  ?  0
KIKL	D1.0E8:	1.0↑8  ?  0

]		;END OF IFN DBFLAG
;HERE ON FLONUMS < 0.01 (DB%) OR < 0.1 (DB$)
FP4:	JUMPN T,FP4E		;FLOATING POINT "E" FORMAT
DB$	CAILE B,33		;FOR DOUBLE PRECISION,
DB$	 PUSH P,[[%D% ? JRST FP4A]]	;PRINT "0.0D0" CLEVERLY
	PUSHJ P,FP4A		;CLEVER WAY TO PRINT OUT "0.0" QUICKLY
	%DCML%
FP4A:	MOVEI A,"0
	JRST (R)

;HERE ON FLONUMS >= 1.0E8
FP4E0:
KA	FDVL T,[1.0↑8]		;BE DOUBLY PRECISE IN DIVIDING
KA	FDVR TT,[1.0↑8]		; BY 10↑8 TO GET NUMBER IN RANGE
KA	FADL T,TT
KIKL	DFDV T,D1.0E8
IFN DBFLAG,[
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
KA	FDVL T,[1.0↑8]		;DIVIDE MASK TOO
KA	FDV TT,[1.0↑8]		;UNROUNDED!
KA	FADL T,TT
KIKL	DFDV T,D1.0E8
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
]		;END OF IFN DBFLAG
	ADDI F,8
	CAML T,[1.0↑8]
	 JRST FP4E0		;KEEP DIVIDING UNTIL < 10↑8
FP4E1:	CAMGE T,[10.0]
	 JRST FP4B
KA	FDVL T,[10.0]		;NOW REDUCE UNTIL < 10.0
KA	FDVRI TT,(10.0)
KA	FADL T,TT
KIKL	DFDV T,D10.0
IFN DBFLAG,[
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
KA	FDVL T,[10.0]		;DIVIDE MASK TOO
KA	FDV TT,[10.0]		;UNROUNDED!
KA	FADL T,TT
KIKL	DFDV T,D10.0
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
]		;END OF IFN DBFLAG
	AOJA F,FP4E1

;HERE FOR NON-ZERO FLONUMS < 0.01 (DB%) OR < 0.1 (DB$)
FP4E:	CAML T,[1.0↑-8]		;BE DOUBLY PRECISE IN MULTIPLYING BY 10↑8
	 JRST FP4E2A
KA	FMPR TT,[1.0↑8]
KA	MOVEM TT,D
KA	FMPL T,[1.0↑8]
KA	UFA TT,D
KA	FADL T,D
KIKL	DFMP T,D1.0E8
IFN DBFLAG,[
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
KA	FMP TT,[1.0↑8]		;UNROUNDED!  MULTIPLY MASK TOO
KA	MOVEM TT,D
KA	FMPL T,[1.0↑8]
KA	UFA TT,D
KA	FADL T,D
KIKL	DFMP T,D1.0E8
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
]		;END OF IFN DBFLAG
	SUBI F,8
	JRST FP4E

FP4E2:
KA	FMPRI TT,(10.0)		;NOW INCREASE UNTIL >= 1.0
KA	MOVEM TT,D
KA	FMPL T,[10.0]
KA	UFA TT,D
KA	FADL T,D
KIKL	DFMP T,D10.0
IFN DBFLAG,[
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
KA	FMP TT,[10.0]		;UNROUNDED!  MULTIPLY MASK TOO
KA	MOVEM TT,D
KA	FMPL T,[10.0]
KA	UFA TT,D
KA	FADL T,D
KIKL	DFMP T,D10.0
	EXCH T,-1(FXP)
	EXCH TT,(FXP)
]		;END OF IFN DBFLAG
FP4E2A:	CAMGE T,[1.0]
	 SOJA F,FP4E2
;HERE WHEN NUMBER BETWEEN 1.0 (INCL) AND 10.0 (EXCL); F IS THE EXPONENT TO BE PRINTED.
FP4B:
IFE DBFLAG,[
KIKL	TLNN TT,200000		;DECIDE WHETHER ROUNDING WILL HAVE ANY EFFECT
KIKL	 JRST FP4B1
KIKL	HLLZ TT,T		;IF SO, CREATE A FLONUM WHOSE VALUE IS
KIKL	TLZ TT,777		; 1/2 LSB OF FRACTION IN T
KIKL	ADD TT,[777000,,1]
	FADR T,TT		;ADD LOW PART TO HIGH PART, ROUNDING
	CAMGE T,[10.0]		;ROUNDING UP MAY TAKE US OUT OF RANGE AGAIN
	 JRST FP4B1
	FDVRI T,(10.0)
	ADDI F,1		;ADJUST EXPONENT FOR THE DIVISION
]		;END OF IFE DBFLAG
;FOR DB$, JUST LET THE EXTRA INFO BITS SIT THERE, EVEN FOR SINGLE PRECISION!
; AFTER ALL, THE MASK HAS ALSO BEEN COMPUTED TO DOUBLE PRECISION
FP4B1:	PUSH FLP,F		;DON'T USE FXP!  WILL CONFLICT WITH MASK FOR DB$
	PUSHJ P,FP3		;NUMBER HAS BEEN NORMALIZED FOR  1.0 .LE. X < 10.0
DB$	CAILE B,33
DB$	 %D%			;FOR DOUBLE PRECISION, "D" INDICATES EXPONENT
DB$	CAIG B,33
	 %E%			;FOR SINGLE PRECISION, "E" INDICATES EXPONENT
	POP FLP,TT		;POP EXPONENT
	SKIPLE TT		;PRINT SIGN (BUT PRINT NO SIGN FOR 0)
	 %POS%
	SKIPGE TT
	 %NEG%
	MOVEI C,10.
	MOVMS TT
	JRST PRINI3		;PRINT EXPONENT AS A DECIMAL INTEGER
SUBTTL	PRINT A COMPLEX OR A DUPLEX

IFN CXFLAG,[
PRINCX:
IFN USELESS,[
	MOVEI T,35.
	SKIPN @-1(P)
	 MOVEI T,18.
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
	SKIPE T,@-1(P)		;DON'T PRINT REAL PART IF 0
	 PUSHJ P,FP0
KA	HRRZ A,-1(P)
KA	MOVE T,(A)
KA	MOVE TT,1(A)
KIKL	DMOVE T,@-1(P)
	JUMPE T,PRNCX2
	SKIPL TT
	 %POS%
PRNCX2:	JUMPE TT,PRNCX4
	SKIPGE TT
	 %NEG%
	MOVM T,TT
	PUSHJ P,FP0
PRNCX3:	MOVEI A,"J		;CROCK
	JRST (R)

PRNCX4:	MOVEI A,"0
	PUSHJ P,(R)
	JRST PRNCX3
]		;END OF IFN CXFLAG

IFN DXFLAG,[
PRINDX:
IFN USELESS,[
	MOVEI T,60.
	SKIPN @-1(P)
	 MOVEI T,30.
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
KA	HRRZ A,-1(P)
KA	MOVE T,(A)
KA	MOVE TT,1(A)
KIKL	DMOVE T,@-1(P)
	SKIPE T			;DON'T PRINT REAL PART IF 0
	 PUSHJ P,DFP0
	HRRZ A,-1(P)
KA	MOVE T,2(A)
KA	MOVE TT,3(A)
KIKL	DMOVE T,2(A)
	SKIPN @-1(P)
	 JRST PRNDX2
	SKIPL T
	 %POS%
PRNDX2:	JUMPE T,PRNCX4
	SKIPGE T
	 %NEG%
	JUMPGE T,PRNDX5
KA	DFN T,TT
KIKL	DMOVN T,T
PRNDX5:	PUSHJ P,DFP0
	JRST PRNCX3
]		;END OF IFN DXFLAG
IFN BIGNUM,[

SUBTTL	PRINT A BIGNUM

PRINB:
IFN USELESS,[
	HRRZ B,@-1(P)
	MOVEI T,1
PRINB0:	ADDI T,12.
	HRRZ B,(B)
	JUMPN B,PRINB0
	PUSHJ P,PRINLP
]		;END OF IFN USELESS
	HRRZ A,-1(P)
	SKIPGE A,(A)
	JRST PRINBQ
IFE USELESS,	HRRZ D,@VBASE
IFN USELESS,[
	HRRZ D,VBASE
	CAIE D,QROMAN
	SKIPA D,(D)
	MOVEI D,10.
]		;END OF IFN USELESS
	CAILE D,10.
	 %POS%
	JRST PRINBZ
PRINBQ:	%NEG%		;NEGATIVE BIGNUM
PRINBZ:	MOVEM R,RSAVE
	HRRZM P,FSAVE	;STORE PDL POSITION SO AR1 AND AR2A CAN BE FOUND
	PUSH P,AR1
	PUSH P,AR2A
	PUSHJ P,YPOCB
	PUSH P,A
	PUSH P,[PRINB4]
	MOVE B,VBASE
IFN USELESS,[
	CAIN B,QROMAN
	SKIPA D,[10.]
]		;END OF IFN USELESS
	JSP T,FXNV2
	MOVE C,D
	JSP T,PRI.
	MOVE R,D
	MOVEI F,1
	MOVE T,D
PRBAB:	MUL T,D
	JUMPN T,.+4
	MOVE T,TT
	MOVE R,TT
	AOJA F,PRBAB
	MOVEM F,NORMF
	MOVE D,R
PRINB3:	MOVE C,A
	HLRZ B,(C)
	MOVE F,(B)
	MOVEI R,0
PNFBLP:	DIV R,D
	MOVEM R,(B)
	MOVE B,(C)
	TRNN B,-1
	JRST PRBFIN
	MOVE C,(C)
	MOVE R,F
	HLRZ B,(C)
	MOVE F,(B)
	JRST PNFBLP

PRBFNA:	HLR A,B
PRBFIN:	MOVS B,(A)
	TLNE B,-1
	SKIPE (B)
	JRST .+2
	JRST PRBFNA
	PUSH FXP,F
	MOVE R,(A)
	TRNN R,-1
	JRST PRBNUF
	PUSHJ P,PRINB3
PRINBI:	POP FXP,TT
	MOVE F,NORMF
	MOVE R,RSAVE
PRINBJ:	SETZ T,
	JSP D,PRINI5
	SOJE F,FP7A1
	MOVE TT,T
	PUSHJ P,PRINBJ
	JRST FP7A1

PRBNUF:	HLRZ A,R
	MOVE TT,(A)
	MOVE AR2A,FSAVE
	MOVE AR1,1(AR2A)	;RESTORE AR1 AND AR2A
	MOVE AR2A,2(AR2A)
	HRRZ C,VBASE
IFN USELESS,	CAIN C,QROMAN
IFN USELESS,	SKIPA R,[10.]
	JSP T,FXNV3
	MOVE C,R
	MOVE R,RSAVE
	SKIPE TT
	PUSHJ P,PRINI3
	JRST PRINBI

PRINB4:	POP P,A
	MOVEI B,TRUTH
	PUSHJ P,RECLAIM
	POP P,AR2A
	POP P,AR1
	POPJ P,
]		;END OF IFN BIGNUM
SUBTTL	FLATSIZE, FLATC, EXPLODEC, EXPLODEN, EXPLODE

FLATSIZE:
	PUSH P,CFIX1		;SUBR 1
	SKIPA R,CFLAT2		;POPJ IS POSITIVE
FLAT4:	 HRROI R,FLAT2
FLAT3:	SETZM FLAT1
	PUSHJ P,PRINTF
	SKIPA TT,FLAT1
FLAT2:	 AOS FLAT1
CFLAT2:	POPJ P,FLAT2

FLATC:	PUSH P,CFIX1		;SUBR 1
	JSP T,SPATOM
	 JRST FLAT4
	JUMPN A,FLATC1
	MOVEI TT,3		;FLATC OF NIL IS 3
	POPJ P,

FLATC1:	HLRZ TT,(A)		;FAST-FLATC FOR SYMBOLS
	HRRZ A,1(TT)
	SETZ TT,
FLATC2:	HRRZ B,(A)		;COUNT 5 CHARS PER PNAME WORD
	ADDI TT,BYTSWD
	JUMPE B,FLATC3
	HRRZ A,(B)
	ADDI TT,BYTSWD
	JUMPN A,FLATC2
	MOVEI A,(B)
FLATC3:	HLRZ A,(A)		;LAST PNAME WORD MAY BE PARTIAL
	SKIPN T,(A)		;WATCH OUT FOR NULL PNAME!
	 SUBI TT,1
	TRNE T,177←1
	 POPJ P,
	TRNE T,177←10
	 SOJA TT,CPOPJ
	SUBI TT,3
	TDNE T,[177←17]
	 AOJA TT,CPOPJ
	TLNN T,(177←26)
	 SUBI TT,1
	POPJ P,

$EXPLODEC:
	SKIPA R,EXPLODE		;SUBR 1	;HRRZI IS NEGATIVE!!!
$$EXPLODEN:
	HRROI R,EXPL2		;SUBR 1
	SKOTT A,SY
	JRST EXPL4
	HLRZ T,(A)
	HRRZ A,1(T)
	PUSH P,R70		;FORMING LIST OF CHARS
	MOVEI B,(P)
	PUSH P,A
	PUSH P,B
	XOR R,EXPLODE
	PUSH FXP,R
EXPLY1:	SKIPN A,-1(P)
	JRST EXPLY9
	HLRZ B,(A)
	MOVE D,(B)
	HRRZ A,(A)
	MOVEM A,-1(P)
EXPLY2:	JUMPE D,EXPLY1
	SETZ TT,
	LSHC TT,7
	SKIPE (FXP)
	JRST EXPLY3
	PUSH FXP,D
	PUSHJ P,RDCH2
	POP FXP,D
	JRST EXPLY4
EXPLY3:	MOVEI A,IN0(TT)		.SEE HINUM
EXPLY4:	PUSHJ P,NCONS
	HRRM A,@(P)
	HRRZM A,(P)
	JRST EXPLY2

EXPLY9:	SUB P,R70+2
	SUB FXP,R70+1
	JRST POPAJ
EXPLODE: HRRZI R,EXPL1		;SUBR 1
EXPL4:	PUSH P,R70
	HRRZM P,EXPL5
	PUSHJ P,PRINTF
	JRST POPAJ

EXPL1:	SAVE B C
	SAVEFX TT R
	ANDI A,177
	PUSHJ P,RDCH3
	POP P,C
EXPL3:	PUSHJ P,NCONS
	HRRM A,@EXPL5
	HRRZM A,EXPL5
EXPL6:	RSTRFX R TT
	JRST POPBJ

EXPL2:	PUSH P,B
	SAVEFX TT R
	MOVEI A,IN0(A)
	JRST EXPL3

SUBTTL	BAKTRACE

BAKTRACE:			;PRINT A BAKTRACE
	JSP TT,LWNACK
	LA03,,QBAKTRACE
	MOVNI TT,1
	JRST BKTR0
BAKLIST:			;RETURN A LIST (SIMILAR TO PRINTED FORMAT)
	JSP TT,LWNACK
	LA01,,QBAKLIST
	MOVSI TT,400000
BKTR0:	MOVEM TT,BACTYF		;TYPE FLAG FOR BAKTRACE/BAKLIST
	MOVEI A,NIL		;START WITH NIL
	SKIPE T			;OR USER SUPPLIED ARG
	 POP P,A
	JSP R,GTPDLP		;GET APPROPRIATE PDL POINTER
		0
	 JFCL
	MOVEI A,(D)		;SAVE PDL POINTER IN A
	MOVE B,(A)		;GET TOP OF STACK
	CAME B,[QBAKTRACE,,CPOPJ]
	 CAMN B,[QBAKLIST,,CPOPJ]
	  SOS A			;SKIP FIRST SLOT IF CALL TO US
	MOVEI R,60		;LOOK AT ABOUT 60 STACK LOCATIONS
	HRRZ TT,C2		;GET PDL ORIGION
	SUBM A,TT		;SAVE PDL OFFSET IN TT
	CAIG TT,(R)		;FEWER THAN 60 LOCATIONS TO LOOK AT?
	 MOVE R,TT		;YES, SO LOOK AT THAT MANY
	MOVE T,A
	SETZM CPJSW		;ASSUME *RSET HAS BEEN OFF
	MOVEI B,CPOPJ
BKTR3:	MOVE TT,(T)		;CUT OUT STUFF FROM *RSET LOOP, IF USED
	CAIN B,(TT)
	 TLNN TT,-1
	  SKIPA
	   SETOM CPJSW		;APPARENTLY *RSET HAS BEEN ON
	TLZ TT,-1#10000
	CAMN TT,[10000,,LSPRET]
	 MOVEI A,-1(T)
	SOS T
	SOJG R,BKTR3
	MOVEM A,BKTRP		;SET UP FOR BAKTRACE LOOP AND GO THERE
	MOVE A,BACTYF
	AOJE A,BKTR2		;IF TRACING THEN SKIP LIST HACKING STUFF
	PUSH P,R70		;SET UP LIST TO HOLD BAKLISTING
	HRLM P,(P)		;SET UP LAST-OF-LIST POINTER
BKTR2:	HRRZ A,C2		;THE PDL-HUNTING LOOP
	ADDI A,1
	CAML A,BKTRP
	 JRST BKTR2X		;EXIT WHEN BACKED UP TO BOTTOM OF PDL
	AOSN BACTYF
	 STRT [SIXBIT \↑MBAKTRACE↑M!\]
	HRRZ A,@BKTRP
	CAIN A,CPOPJ		;IN *RSET MODE, THIS IS A TAG
	 JRST BKTR1C		;PUT ON PDL UPON ENTRY TO A FUNCTION
	CAIN A,ILIST3
	 JRST BKTR1B
	MOVE D,@BKTRP
	TLNE D,10000#-1		;TO BE A PUSHJ RETURN ADDR, THERE MUST 
	 CAIN A,BKCOM1		; BE PC FLAGS IN LH
	  JRST BKTR1
	CAIL A,BEGFUN
	 CAIL A,ENDFUN
	  JRST BKTR1A
	CAIE A,CON2
	 CAIN A,CON3
	  JRST BKTR1G
	CAIN A,PG0A
	 JRST BKTR1E
	CAIN A,LMBLP1
	 JRST BKTR1
	CAILE A,BRLP1
	 CAILE A,BRLP2
	  SKIPA
	   JRST BKTR1H
Q%	CAIN A,RDIN3B
Q%	 JRST BKTRR5
Q%	CAIE A,RDIN3A
	 CAIN A,REKRD1
	  JRST BKTRR3
	CAIE A,UNBIND
	 JRST BKTR1A
BKTR1:	SOS BKTRP
	JRST BKTR2
BKTR2X:	AOSE BACTYF
	 SKIPL BACTYF
	  JRST TERPRI
	POP P,A
	JRST RHAPJ
BKTR1A:	CAMGE A,@VBPORG		;LETS HOPE THAT BPORG ISN'T SCREWED UP
	 CAIGE A,BBPSSG
	  JRST BKTR1
BK1A2:	MOVEI AR1,-1(A)
BK1A4:	HLRZ B,-1(A)		;SOMEWHERE IN BINARY PROGRAMS
	MOVEI R,PRIN1B		;IF "CALL", THEN SUBR ATOM NAME WILL BE IN B
	TRC B,37		;LIKELY NOT AN INSTRUCTION IF ALL THE INDIRECT,
	TRCE B,37		; AND INDEXING BITS ARE ONES
	 CAIGE B,(CALL )
	  JRST BKTR1
	CAIG B,(JCALLF 17,)
	 JRST BK1A1
	CAIE B,(XCT)		;MIGHT BE A XCT OF A CALL, JRST, PUSHJ TO SUBR
	 JRST .+3
	   HRRZ A,-1(A)		;IF SO, CYCLE TO TRY TO FIND CALLED SUBR NAME
	   AOJA A,BK1A4
	MOVEI R,ERRADR		;HA! MAYBE  PUSHJ OR JRST, SO NOW WE HAVE 
	CAIN B,(JRST 0,)	; ONLY BEGINNING ADDRESS OF SUBR.  HENCE
	 JRST BK1A1		; IT HAS TO BE DECODED INTO ATOM NAME.
	CAIE B,(PUSHJ P,)
	 JRST BKTR1		;LOSE, DON'T KNOW WHAT KIND OF INST THIS IS
	HLLZ B,@BKTRP
	TLNN B,10000		;USER MODE FLAG - STOPS RANDOM
	 JRST BKTR1		; DATA NOT ENTERED BY PUSHJ

BK1A1:	MOVE B,-1(A)		;EITHER "(J)CALL(F)", "JRST", OR "PUSHJ P,"
	TLNE B,7777760		;LET INDIRECTION HAPPEN, BUT CAN'T CHANCE 
	 TLNE B,((17))		;  DOING IT IF THE UUO IS INDEXED, OR 
	  JRST BK1A1B		;  ADDRESSES AN AC
	MOVEI B,@-1(A)		;LET INDIRECT DO ITS THING
BK1A1C:	PUSH P,AR1		;ORIGINAL PC WHEREFROM SUBR WAS CALLED
	SKIPGE BACTYF
	 JRST BK1A3
	PUSHJ P,(R)		;R HAS EITHER PRIN1B OR ERRADR
	STRT [SIXBIT \←!\]	;  DEPENDING ON WHETHER "CALL" OR "PUSHJ P,"
	POP P,B
	PUSHJ P,ERRADR
	STRT [SIXBIT \ !\]
	JRST BKTR1

BK1A3:	CAIE R,ERRADR
	 SKIPA A,B
	  PUSHJ P,ERRDCD	;"ERRDCD" DECODES ADDRESS IN B, GETS ATOM IN A
	EXCH A,(P)
	PUSHJ P,ERRDCD
	PUSH P,[QLA]
	PUSH P,A
	MOVNI T,3
	JRST BKT1F2

BK1A1B:	CAIN R,ERRADR
	 TDZA B,B
	  MOVEI B,QM
	JRST BK1A1C
BKTR1B:	MOVE D,BKTRP
	HRRZ B,-1(D)	;PROBABLY FOR ENTRY TO SOME SUBR, LSUBR, OR EXPR
	CAIE B,ELSB1	;LISTING TINGS UP ON THE PDL
	 CAIN B,ESB1
	  JRST .+3
	CAIE B,IAPPLY
	 JRST BKTR1
	HLRE B,-1(D)
	ADDI B,-3(D)
	HLRZ A,(B)
	JUMPE A,BKTR1
	HRRZM B,BKTRP
	SKIPGE BACTYF
	 JRST BKT1B1
	STRT [SIXBIT \(!\]
	PUSHJ P,PRINC
	STRT [SIXBIT \ EVALARGS) !\]
	JRST BKTR1

BKTR1C:	HLRZ A,@BKTRP	;PROBABLY ENTERED AN F-TYPE FUNCTION
	JUMPE A,BKTR1	;WELL, NIL ISN'T REALLY A FUNCTION
BKTR1F:	SKIPGE BACTYF
	JRST BKT1F1
	PUSHJ P,PRINC
	STRT [SIXBIT \← !\]
	JRST BKTR1

BKT1B1:	SKIPA B,[QEVALARGS]
BKT1F1:	 MOVEI B,QLA
	PUSH P,A
	PUSH P,B
	MOVNI T,2
BKT1F2:	PUSHJ FXP,LISTX
	PUSHJ P,NCONS
	HLRZ B,(P)
	HRRM A,(B)	;NCONC MOST RECENT GOODIE ONTO END OF LIST
	HRLM A,(P)	;UPDATE LAST-OF-LIST POINTER
	JRST BKTR1

BKTR1H:	MOVNI T,LERSTP+5-1	;2 FROM BREAK, 2 FROM EDERRL, 1 FROM BRLP = 5
	MOVEI A,QBREAK		;-1 SINCE BKTR1 WILL TAKE OFF ONE MORE
	JRST BKTR1D
BKTR1E:	MOVNI T,LPRP		;BACK UP OFF A PROG
	MOVEI A,QPROG
BKTR1D:	ADDM T,BKTRP
	JRST BKTR1I

BKTR1G:	MOVEI A,QCOND		;FOUND A COND ENTRY
BKTR1I:	SKIPE CPJSW
	 JRST BKTR1		;IF *RSET WAS ON, ENTRY IS BE MARKED BY CPOPJ
	JRST BKTR1F

BKTRR3:	SKIPA T,XC-3
BKTRR5:	 MOVNI T,5
	ADDM T,BKTRP
	JRST BKTR1


PGTOP PRT,[PRINT,TYO,EXPLODE,FLATC,BAKTRACE,ETC]